You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iggy.apache.org by hg...@apache.org on 2026/05/28 08:52:37 UTC

(iggy) 01/01: fix(cli): swap libdbus-backed keyring for pure-Rust zbus (#1710)

This is an automated email from the ASF dual-hosted git repository.

hubcio pushed a commit to branch drop-libdbus-sys
in repository https://gitbox.apache.org/repos/asf/iggy.git

commit b9ce11a2107932c54544f9d3dc3aed243739fd35
Author: Hubert Gruszecki <h....@gmail.com>
AuthorDate: Wed May 27 11:45:43 2026 +0200

    fix(cli): swap libdbus-backed keyring for pure-Rust zbus (#1710)
    
    libdbus-sys vendored build fails on FreeBSD with
    "Unsupported platform" (diwic/dbus-rs#497, upstream
    declined to fix), blocking iggy-cli on every Tier-2
    target that lacks libdbus-1.
    
    Replace dbus-secret-service-keyring-store with
    zbus-secret-service-keyring-store on Linux. Both crates
    target the same org.freedesktop.Secret D-Bus service,
    so existing gnome-keyring / KWallet / KeePassXC entries
    round-trip unchanged. zbus is pure Rust: no libdbus-sys,
    no libdbus-1 system package, no vendored C build, no
    unsafe FFI on the keyring path.
    
    Picks the `rt-async-io-crypto-rust` feature, NOT
    `rt-tokio-*`: under the tokio feature, zbus::block_on
    constructs a fresh multi-thread runtime and blocks onq
    it, which panics when invoked from inside the CLI's
    block_on runs on a parker thread and is safe from any
    async context.
    
    Drops the aarch64-musl `CFLAGS=-mno-outline-atomics`
    linker hack from CI; it only existed for the libdbus
    C build.
---
 .github/actions/rust/pre-merge/action.yml          |   3 -
 .github/workflows/_build_rust_artifacts.yml        |   6 -
 Cargo.lock                                         | 412 +++++++++++++++------
 Cargo.toml                                         |   3 +-
 core/cli/Cargo.toml                                |  14 +-
 .../tests/cli/common/keyring.rs => cli/build.rs}   |  39 +-
 core/cli/src/commands/binary_system/session.rs     |  10 +-
 core/integration/Cargo.toml                        |  12 +-
 .../{tests/cli/common/keyring.rs => build.rs}      |  27 +-
 core/integration/tests/cli/common/keyring.rs       |  44 ++-
 10 files changed, 390 insertions(+), 180 deletions(-)

diff --git a/.github/actions/rust/pre-merge/action.yml b/.github/actions/rust/pre-merge/action.yml
index b09d036e6..4e083b9eb 100644
--- a/.github/actions/rust/pre-merge/action.yml
+++ b/.github/actions/rust/pre-merge/action.yml
@@ -354,9 +354,6 @@ runs:
         --exclude bench-dashboard-frontend
       shell: bash
       env:
-        # Disable GCC outline atomics to avoid undefined __aarch64_ldadd4_sync
-        # references when linking dbus-sys (required by keyring crate)
-        CFLAGS: "-mno-outline-atomics"
         PKG_CONFIG_ALLOW_CROSS: "1"
         PKG_CONFIG_ALL_STATIC: "1"
 
diff --git a/.github/workflows/_build_rust_artifacts.yml b/.github/workflows/_build_rust_artifacts.yml
index 268c7b1b6..404a501e9 100644
--- a/.github/workflows/_build_rust_artifacts.yml
+++ b/.github/workflows/_build_rust_artifacts.yml
@@ -135,12 +135,6 @@ jobs:
             export PKG_CONFIG_ALL_STATIC=1
           fi
 
-          # aarch64 musl: disable GCC outline atomics to avoid undefined __aarch64_ldadd4_sync
-          # references when linking dbus-sys (required by keyring crate)
-          if [[ "${{ matrix.target }}" == "aarch64-unknown-linux-musl" ]]; then
-            export CFLAGS="-mno-outline-atomics"
-          fi
-
           # musl builds: use musl-gcc as linker to ensure proper linking against musl libc
           if [[ "${{ matrix.libc }}" == "musl" ]]; then
             export CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER=musl-gcc
diff --git a/Cargo.lock b/Cargo.lock
index 2f6280f0d..97007571e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1063,6 +1063,38 @@ dependencies = [
  "tokio",
 ]
 
+[[package]]
+name = "async-executor"
+version = "1.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c96bf972d85afc50bf5ab8fe2d54d1586b4e0b46c97c50a0c9e71e2f7bcd812a"
+dependencies = [
+ "async-task",
+ "concurrent-queue",
+ "fastrand",
+ "futures-lite",
+ "pin-project-lite",
+ "slab",
+]
+
+[[package]]
+name = "async-io"
+version = "2.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc"
+dependencies = [
+ "autocfg",
+ "cfg-if",
+ "concurrent-queue",
+ "futures-io",
+ "futures-lite",
+ "parking",
+ "polling",
+ "rustix 1.1.4",
+ "slab",
+ "windows-sys 0.61.2",
+]
+
 [[package]]
 name = "async-lock"
 version = "3.4.2"
@@ -1074,6 +1106,35 @@ dependencies = [
  "pin-project-lite",
 ]
 
+[[package]]
+name = "async-process"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fc50921ec0055cdd8a16de48773bfeec5c972598674347252c0399676be7da75"
+dependencies = [
+ "async-channel",
+ "async-io",
+ "async-lock",
+ "async-signal",
+ "async-task",
+ "blocking",
+ "cfg-if",
+ "event-listener",
+ "futures-lite",
+ "rustix 1.1.4",
+]
+
+[[package]]
+name = "async-recursion"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.117",
+]
+
 [[package]]
 name = "async-scoped"
 version = "0.9.0"
@@ -1085,6 +1146,24 @@ dependencies = [
  "tokio",
 ]
 
+[[package]]
+name = "async-signal"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "52b5aaafa020cf5053a01f2a60e8ff5dccf550f0f77ec54a4e47285ac2bab485"
+dependencies = [
+ "async-io",
+ "async-lock",
+ "atomic-waker",
+ "cfg-if",
+ "futures-core",
+ "futures-io",
+ "rustix 1.1.4",
+ "signal-hook-registry",
+ "slab",
+ "windows-sys 0.61.2",
+]
+
 [[package]]
 name = "async-stream"
 version = "0.3.6"
@@ -2034,6 +2113,19 @@ dependencies = [
  "objc2",
 ]
 
+[[package]]
+name = "blocking"
+version = "1.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e83f8d02be6967315521be875afa792a316e28d57b5a2d401897e2a7921b7f21"
+dependencies = [
+ "async-channel",
+ "async-task",
+ "futures-io",
+ "futures-lite",
+ "piper",
+]
+
 [[package]]
 name = "bnum"
 version = "0.12.1"
@@ -3648,46 +3740,6 @@ version = "0.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "be1e0bca6c3637f992fc1cc7cbc52a78c1ef6db076dbf1059c4323d6a2048376"
 
-[[package]]
-name = "dbus"
-version = "0.9.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b942602992bb7acfd1f51c49811c58a610ef9181b6e66f3e519d79b540a3bf73"
-dependencies = [
- "libc",
- "libdbus-sys",
- "windows-sys 0.61.2",
-]
-
-[[package]]
-name = "dbus-secret-service"
-version = "4.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "708b509edf7889e53d7efb0ffadd994cc6c2345ccb62f55cfd6b0682165e4fa6"
-dependencies = [
- "aes",
- "block-padding",
- "cbc",
- "dbus",
- "fastrand",
- "hkdf 0.12.4",
- "num",
- "once_cell",
- "openssl",
- "sha2 0.10.9",
- "zeroize",
-]
-
-[[package]]
-name = "dbus-secret-service-keyring-store"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "21d8f54da401bb5eb2a4d873ac4b359f4a599df2ca8634bb5b8c045e5ee78757"
-dependencies = [
- "dbus-secret-service",
- "keyring-core",
-]
-
 [[package]]
 name = "deadpool"
 version = "0.12.3"
@@ -4396,6 +4448,33 @@ dependencies = [
  "cfg-if",
 ]
 
+[[package]]
+name = "endi"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "66b7e2430c6dff6a955451e2cfc438f09cea1965a9d6f87f7e3b90decc014099"
+
+[[package]]
+name = "enumflags2"
+version = "0.7.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1027f7680c853e056ebcec683615fb6fbbc07dbaa13b4d5d9442b146ded4ecef"
+dependencies = [
+ "enumflags2_derive",
+ "serde",
+]
+
+[[package]]
+name = "enumflags2_derive"
+version = "0.7.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.117",
+]
+
 [[package]]
 name = "enumset"
 version = "1.1.13"
@@ -4800,21 +4879,6 @@ dependencies = [
  "ttf-parser",
 ]
 
-[[package]]
-name = "foreign-types"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
-dependencies = [
- "foreign-types-shared",
-]
-
-[[package]]
-name = "foreign-types-shared"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
-
 [[package]]
 name = "form_urlencoded"
 version = "1.2.2"
@@ -6473,11 +6537,11 @@ dependencies = [
  "apple-native-keyring-store",
  "async-trait",
  "bytes",
+ "cfg_aliases",
  "chrono",
  "clap",
  "clap_complete",
  "comfy-table",
- "dbus-secret-service-keyring-store",
  "dirs",
  "figlet-rs",
  "iggy",
@@ -6496,6 +6560,7 @@ dependencies = [
  "tracing-appender",
  "tracing-subscriber",
  "windows-native-keyring-store",
+ "zbus-secret-service-keyring-store",
 ]
 
 [[package]]
@@ -7105,11 +7170,11 @@ dependencies = [
  "base64",
  "bon",
  "bytes",
+ "cfg_aliases",
  "compio",
  "configs",
  "configs_derive",
  "ctor 1.0.6",
- "dbus-secret-service-keyring-store",
  "deltalake",
  "dtor 1.0.3",
  "figment",
@@ -7153,6 +7218,7 @@ dependencies = [
  "url",
  "uuid",
  "wiremock",
+ "zbus-secret-service-keyring-store",
  "zip 8.6.0",
 ]
 
@@ -7614,16 +7680,6 @@ version = "0.2.186"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
 
-[[package]]
-name = "libdbus-sys"
-version = "0.2.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "328c4789d42200f1eeec05bd86c9c13c7f091d2ba9a6ea35acdf51f31bc0f043"
-dependencies = [
- "cc",
- "pkg-config",
-]
-
 [[package]]
 name = "libfuzzer-sys"
 version = "0.4.12"
@@ -8033,6 +8089,15 @@ dependencies = [
  "libc",
 ]
 
+[[package]]
+name = "memoffset"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
+dependencies = [
+ "autocfg",
+]
+
 [[package]]
 name = "message_bus"
 version = "0.1.0"
@@ -8805,59 +8870,12 @@ dependencies = [
  "uuid",
 ]
 
-[[package]]
-name = "openssl"
-version = "0.10.80"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a45fa2aa886c42762255da344f0a0d313e254066c46aad76f300c3d3da62d967"
-dependencies = [
- "bitflags 2.11.1",
- "cfg-if",
- "foreign-types",
- "libc",
- "openssl-macros",
- "openssl-sys",
-]
-
-[[package]]
-name = "openssl-macros"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.117",
-]
-
 [[package]]
 name = "openssl-probe"
 version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe"
 
-[[package]]
-name = "openssl-src"
-version = "300.6.0+3.6.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a8e8cbfd3a4a8c8f089147fd7aaa33cf8c7450c4d09f8f80698a0cf093abeff4"
-dependencies = [
- "cc",
-]
-
-[[package]]
-name = "openssl-sys"
-version = "0.9.116"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f28a22dc7140cda5f096e5e7724a6962ca81a7f8bfd2979f9b18c11af56318c4"
-dependencies = [
- "cc",
- "libc",
- "openssl-src",
- "pkg-config",
- "vcpkg",
-]
-
 [[package]]
 name = "opentelemetry"
 version = "0.32.0"
@@ -8988,6 +9006,16 @@ dependencies = [
  "hashbrown 0.14.5",
 ]
 
+[[package]]
+name = "ordered-stream"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50"
+dependencies = [
+ "futures-core",
+ "pin-project-lite",
+]
+
 [[package]]
 name = "os_pipe"
 version = "1.2.3"
@@ -9422,6 +9450,17 @@ dependencies = [
  "thiserror 1.0.69",
 ]
 
+[[package]]
+name = "piper"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c835479a4443ded371d6c535cbfd8d31ad92c5d23ae9770a61bc155e4992a3c1"
+dependencies = [
+ "atomic-waker",
+ "fastrand",
+ "futures-io",
+]
+
 [[package]]
 name = "pkcs1"
 version = "0.7.5"
@@ -11086,6 +11125,25 @@ dependencies = [
  "zeroize",
 ]
 
+[[package]]
+name = "secret-service"
+version = "5.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a62d7f86047af0077255a29494136b9aaaf697c76ff70b8e49cded4e2623c14"
+dependencies = [
+ "aes",
+ "cbc",
+ "futures-util",
+ "generic-array",
+ "getrandom 0.2.17",
+ "hkdf 0.12.4",
+ "num",
+ "once_cell",
+ "serde",
+ "sha2 0.10.9",
+ "zbus",
+]
+
 [[package]]
 name = "security-framework"
 version = "3.7.0"
@@ -13312,6 +13370,17 @@ version = "0.1.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971"
 
+[[package]]
+name = "uds_windows"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f2f6fb2847f6742cd76af783a2a2c49e9375d0a111c7bef6f71cd9e738c72d6e"
+dependencies = [
+ "memoffset",
+ "tempfile",
+ "windows-sys 0.61.2",
+]
+
 [[package]]
 name = "ulid"
 version = "1.2.1"
@@ -14490,6 +14559,9 @@ name = "winnow"
 version = "1.0.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1"
+dependencies = [
+ "memchr",
+]
 
 [[package]]
 name = "winsafe"
@@ -14789,6 +14861,78 @@ version = "3.0.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c6e61e59a957b7ccee15d2049f86e8bfd6f66968fcd88f018950662d9b86e675"
 
+[[package]]
+name = "zbus"
+version = "5.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3bcbf15c8708d7fc1be0c993622e0a5cbd5e8b52bfa40afa4c3e0cd8d724ac1"
+dependencies = [
+ "async-broadcast",
+ "async-executor",
+ "async-io",
+ "async-lock",
+ "async-process",
+ "async-recursion",
+ "async-task",
+ "async-trait",
+ "blocking",
+ "enumflags2",
+ "event-listener",
+ "futures-core",
+ "futures-lite",
+ "hex",
+ "libc",
+ "ordered-stream",
+ "rustix 1.1.4",
+ "serde",
+ "serde_repr",
+ "tracing",
+ "uds_windows",
+ "uuid",
+ "windows-sys 0.61.2",
+ "winnow 1.0.3",
+ "zbus_macros",
+ "zbus_names",
+ "zvariant",
+]
+
+[[package]]
+name = "zbus-secret-service-keyring-store"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ccede190ba363386a24e8021c7f3848393976609ec9f5d1f8c6c09ef37075b4"
+dependencies = [
+ "keyring-core",
+ "secret-service",
+ "zbus",
+]
+
+[[package]]
+name = "zbus_macros"
+version = "5.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "51fa5406ad9175a8c825a931f8cf347116b531b3634fcb0b627c290f1f2516ff"
+dependencies = [
+ "proc-macro-crate 3.3.0",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.117",
+ "zbus_names",
+ "zvariant",
+ "zvariant_utils",
+]
+
+[[package]]
+name = "zbus_names"
+version = "4.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7074f3e50b894eac91750142016d30d0a89be8e67dbfd9704fb875825760e52d"
+dependencies = [
+ "serde",
+ "winnow 1.0.3",
+ "zvariant",
+]
+
 [[package]]
 name = "zerocopy"
 version = "0.8.48"
@@ -14999,3 +15143,43 @@ checksum = "27bc9d5b815bc103f142aa054f561d9187d191692ec7c2d1e2b4737f8dbd7296"
 dependencies = [
  "zune-core 0.5.1",
 ]
+
+[[package]]
+name = "zvariant"
+version = "5.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1c1567a6ec68df868cbbfde844cfc6d81649fe5109a62b116b19fabd53e618ee"
+dependencies = [
+ "endi",
+ "enumflags2",
+ "serde",
+ "winnow 1.0.3",
+ "zvariant_derive",
+ "zvariant_utils",
+]
+
+[[package]]
+name = "zvariant_derive"
+version = "5.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c7d5b780599bbde114e39d9a0799577fad1ced5105d38515745f7b3099d8ceda"
+dependencies = [
+ "proc-macro-crate 3.3.0",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.117",
+ "zvariant_utils",
+]
+
+[[package]]
+name = "zvariant_utils"
+version = "3.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6d464f5733ffa07a3164d656f18533caace9d0638596721355d73256a410d691"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "serde",
+ "syn 2.0.117",
+ "winnow 1.0.3",
+]
diff --git a/Cargo.toml b/Cargo.toml
index ec0a5b180..2b994b357 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -100,6 +100,7 @@ bon = "3.9.1"
 byte-unit = { version = "5.2.0", default-features = false, features = ["serde", "byte", "std"] }
 bytemuck = { version = "1.25", features = ["derive", "min_const_generics"] }
 bytes = "1.11.1"
+cfg_aliases = "0.2.1"
 charming = "0.6.0"
 chrono = { version = "0.4.44", features = ["serde"] }
 clap = { version = "4.6.1", features = ["derive", "wrap_help"] }
@@ -139,7 +140,6 @@ cyper = { version = "0.8.3", features = ["rustls"], default-features = false }
 cyper-axum = { version = "0.8.0" }
 darling = "0.23"
 dashmap = "6.2.1"
-dbus-secret-service-keyring-store = { version = "1.0.0", features = ["crypto-rust", "vendored"] }
 deltalake = { version = "0.32.3", features = ["azure", "gcs", "s3"] }
 derive-new = "0.7.0"
 derive_builder = "0.20.2"
@@ -329,6 +329,7 @@ webpki-roots = "1.0.7"
 windows-native-keyring-store = "1.1.0"
 yew = { version = "0.23", features = ["csr"] }
 yew-router = "0.20"
+zbus-secret-service-keyring-store = { version = "1.0.0", features = ["rt-async-io-crypto-rust"] }
 zip = { version = "8.6.0", default-features = false, features = ["deflate"] }
 
 [profile.release]
diff --git a/core/cli/Cargo.toml b/core/cli/Cargo.toml
index a99ac41ae..1c4d4ef32 100644
--- a/core/cli/Cargo.toml
+++ b/core/cli/Cargo.toml
@@ -31,6 +31,9 @@ readme = "README.md"
 pkg-url = "{ repo }/releases/download/{ name }-{ version }/{ name }-{ target }{ archive-suffix }"
 bin-dir = "{ bin }{ binary-ext }"
 
+[package.metadata.cargo-machete]
+ignored = ["cfg_aliases"]
+
 [lib]
 name = "iggy_cli"
 path = "src/lib.rs"
@@ -43,7 +46,7 @@ path = "src/main.rs"
 default = ["login-session"]
 login-session = [
     "dep:keyring-core",
-    "dep:dbus-secret-service-keyring-store",
+    "dep:zbus-secret-service-keyring-store",
     "dep:apple-native-keyring-store",
     "dep:windows-native-keyring-store",
 ]
@@ -73,8 +76,10 @@ tracing = { workspace = true }
 tracing-appender = { workspace = true }
 tracing-subscriber = { workspace = true, default-features = false }
 
-[target.'cfg(target_os = "linux")'.dependencies]
-dbus-secret-service-keyring-store = { workspace = true, optional = true }
+# `cfg(secret_service_keyring)` is the cfg_aliases alias for the BSD/Linux
+# desktop platforms; see build.rs.
+[target.'cfg(any(target_os = "linux", target_os = "freebsd", target_os = "dragonfly", target_os = "netbsd", target_os = "openbsd"))'.dependencies]
+zbus-secret-service-keyring-store = { workspace = true, optional = true }
 
 [target.'cfg(target_os = "macos")'.dependencies]
 apple-native-keyring-store = { workspace = true, optional = true }
@@ -82,6 +87,9 @@ apple-native-keyring-store = { workspace = true, optional = true }
 [target.'cfg(target_os = "windows")'.dependencies]
 windows-native-keyring-store = { workspace = true, optional = true }
 
+[build-dependencies]
+cfg_aliases = { workspace = true }
+
 [dev-dependencies]
 tempfile = { workspace = true }
 tokio = { workspace = true, features = ["macros", "rt"] }
diff --git a/core/integration/tests/cli/common/keyring.rs b/core/cli/build.rs
similarity index 51%
copy from core/integration/tests/cli/common/keyring.rs
copy to core/cli/build.rs
index e8e3cf524..4165856cc 100644
--- a/core/integration/tests/cli/common/keyring.rs
+++ b/core/cli/build.rs
@@ -16,21 +16,28 @@
  * under the License.
  */
 
-#[cfg(target_os = "linux")]
-use dbus_secret_service_keyring_store::store::Store;
-#[cfg(target_os = "linux")]
-use std::sync::Once;
+#![recursion_limit = "256"]
 
-/// `keyring-core` 1.x has no implicit default backend; tests must register one
-/// before any `Entry::new` (directly or via `ServerSession`).
-#[cfg(target_os = "linux")]
-pub(crate) fn ensure_keyring_store() {
-    static INIT: Once = Once::new();
-    INIT.call_once(|| {
-        let store = Store::new().expect("Failed to create dbus secret-service store");
-        keyring_core::set_default_store(store);
-    });
+fn main() {
+    cfg_aliases::cfg_aliases! {
+        // Targets that use the freedesktop.org Secret Service (D-Bus) keyring
+        // backend: Linux and BSDs.
+        secret_service_keyring: { any(
+            target_os = "linux",
+            target_os = "freebsd",
+            target_os = "dragonfly",
+            target_os = "netbsd",
+            target_os = "openbsd"
+        ) },
+        // Any target with a native keyring backend wired up.
+        keyring_supported: { any(
+            target_os = "macos",
+            target_os = "windows",
+            target_os = "linux",
+            target_os = "freebsd",
+            target_os = "dragonfly",
+            target_os = "netbsd",
+            target_os = "openbsd"
+        ) },
+    }
 }
-
-#[cfg(not(target_os = "linux"))]
-pub(crate) fn ensure_keyring_store() {}
diff --git a/core/cli/src/commands/binary_system/session.rs b/core/cli/src/commands/binary_system/session.rs
index 8c9e00704..ceeaa146f 100644
--- a/core/cli/src/commands/binary_system/session.rs
+++ b/core/cli/src/commands/binary_system/session.rs
@@ -16,17 +16,17 @@
  * under the License.
  */
 
-#[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))]
+#[cfg(keyring_supported)]
 use std::sync::Mutex;
 
 #[cfg(target_os = "macos")]
 use apple_native_keyring_store::keychain::Store;
-#[cfg(target_os = "linux")]
-use dbus_secret_service_keyring_store::store::Store;
 use keyring_core::{Entry, error::Result};
 use tracing::warn;
 #[cfg(target_os = "windows")]
 use windows_native_keyring_store::store::Store;
+#[cfg(secret_service_keyring)]
+use zbus_secret_service_keyring_store::store::Store;
 
 use crate::commands::cli_command::PRINT_TARGET;
 
@@ -40,7 +40,7 @@ const SESSION_KEYRING_SERVICE_NAME: &str = "iggy-cli-session";
 /// an empty default store and race to install one. `get_default_store()` acts
 /// as the idempotency check, so a transient `Store::new()` failure stays
 /// retryable on the next call.
-#[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))]
+#[cfg(keyring_supported)]
 pub fn ensure_default_store() -> Result<()> {
     static INIT_LOCK: Mutex<()> = Mutex::new(());
     let _guard = INIT_LOCK.lock().unwrap_or_else(|p| p.into_inner());
@@ -52,7 +52,7 @@ pub fn ensure_default_store() -> Result<()> {
     Ok(())
 }
 
-#[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))]
+#[cfg(not(keyring_supported))]
 pub fn ensure_default_store() -> Result<()> {
     Ok(())
 }
diff --git a/core/integration/Cargo.toml b/core/integration/Cargo.toml
index 3142cca88..b0f30cbe5 100644
--- a/core/integration/Cargo.toml
+++ b/core/integration/Cargo.toml
@@ -22,10 +22,15 @@ edition = "2024"
 license = "Apache-2.0"
 publish = false
 
+[package.metadata.cargo-machete]
+ignored = ["cfg_aliases"]
+
 # Some tests are failing in CI due to lack of IPv6 interfaces
 # inside the docker containers. This is a temporary workaround (hopefully).
 [features]
 ci-qemu = []
+default = ["login-session"]
+login-session = ["dep:zbus-secret-service-keyring-store"]
 vsr = ["iggy/vsr"]
 
 [dependencies]
@@ -88,5 +93,8 @@ uuid = { workspace = true }
 wiremock = "0.6"
 zip = { workspace = true }
 
-[target.'cfg(target_os = "linux")'.dependencies]
-dbus-secret-service-keyring-store = { workspace = true }
+[target.'cfg(any(target_os = "linux", target_os = "freebsd", target_os = "dragonfly", target_os = "netbsd", target_os = "openbsd"))'.dependencies]
+zbus-secret-service-keyring-store = { workspace = true, optional = true }
+
+[build-dependencies]
+cfg_aliases = { workspace = true }
diff --git a/core/integration/tests/cli/common/keyring.rs b/core/integration/build.rs
similarity index 56%
copy from core/integration/tests/cli/common/keyring.rs
copy to core/integration/build.rs
index e8e3cf524..53b36ab30 100644
--- a/core/integration/tests/cli/common/keyring.rs
+++ b/core/integration/build.rs
@@ -16,21 +16,16 @@
  * under the License.
  */
 
-#[cfg(target_os = "linux")]
-use dbus_secret_service_keyring_store::store::Store;
-#[cfg(target_os = "linux")]
-use std::sync::Once;
+#![recursion_limit = "256"]
 
-/// `keyring-core` 1.x has no implicit default backend; tests must register one
-/// before any `Entry::new` (directly or via `ServerSession`).
-#[cfg(target_os = "linux")]
-pub(crate) fn ensure_keyring_store() {
-    static INIT: Once = Once::new();
-    INIT.call_once(|| {
-        let store = Store::new().expect("Failed to create dbus secret-service store");
-        keyring_core::set_default_store(store);
-    });
+fn main() {
+    cfg_aliases::cfg_aliases! {
+        secret_service_keyring: { any(
+            target_os = "linux",
+            target_os = "freebsd",
+            target_os = "dragonfly",
+            target_os = "netbsd",
+            target_os = "openbsd"
+        ) },
+    }
 }
-
-#[cfg(not(target_os = "linux"))]
-pub(crate) fn ensure_keyring_store() {}
diff --git a/core/integration/tests/cli/common/keyring.rs b/core/integration/tests/cli/common/keyring.rs
index e8e3cf524..6ce5ae278 100644
--- a/core/integration/tests/cli/common/keyring.rs
+++ b/core/integration/tests/cli/common/keyring.rs
@@ -16,21 +16,37 @@
  * under the License.
  */
 
-#[cfg(target_os = "linux")]
-use dbus_secret_service_keyring_store::store::Store;
-#[cfg(target_os = "linux")]
-use std::sync::Once;
+#[cfg(all(feature = "login-session", secret_service_keyring))]
+mod backend {
+    use std::sync::OnceLock;
+    use zbus_secret_service_keyring_store::store::Store;
 
-/// `keyring-core` 1.x has no implicit default backend; tests must register one
-/// before any `Entry::new` (directly or via `ServerSession`).
-#[cfg(target_os = "linux")]
-pub(crate) fn ensure_keyring_store() {
-    static INIT: Once = Once::new();
-    INIT.call_once(|| {
-        let store = Store::new().expect("Failed to create dbus secret-service store");
-        keyring_core::set_default_store(store);
-    });
+    /// Single global init result. `OnceLock` (not `Once`) so a failed
+    /// `Store::new` doesn't poison the slot and cascade `PoisonError` to every
+    /// subsequent test in the same process; the original error is replayed
+    /// verbatim instead.
+    static KEYRING_INIT: OnceLock<Result<(), String>> = OnceLock::new();
+
+    pub(crate) fn ensure_keyring_store() {
+        let result = KEYRING_INIT.get_or_init(|| match Store::new() {
+            Ok(store) => {
+                keyring_core::set_default_store(store);
+                Ok(())
+            }
+            Err(err) => Err(format!(
+                "failed to create zbus secret-service keyring store: {err}. \
+                 Ensure DBUS_SESSION_BUS_ADDRESS is set and a secret-service \
+                 provider (gnome-keyring-daemon, KWallet, KeePassXC) is running."
+            )),
+        });
+        if let Err(msg) = result {
+            panic!("{msg}");
+        }
+    }
 }
 
-#[cfg(not(target_os = "linux"))]
+#[cfg(all(feature = "login-session", secret_service_keyring))]
+pub(crate) use backend::ensure_keyring_store;
+
+#[cfg(not(all(feature = "login-session", secret_service_keyring)))]
 pub(crate) fn ensure_keyring_store() {}