Skip to content

Why Linux keychain storage uses the Secret Service

On Linux, KeyringStore keeps secrets in the freedesktop Secret Service: the D-Bus API that GNOME Keyring and KWallet implement. Secrets persist across reboots, as they do on macOS and Windows. There is no other Linux backend and no feature that selects one.

What earlier releases did

Until 0.6.5 these docs said the Linux default was kernel keyutils, with the Secret Service as an opt-in behind linux-persistent. That stopped being true at 0.6.0, when the crate moved to keyring 4. Its v1 feature, which this crate enabled, makes the Secret Service the default on Linux, reached through a pure-Rust D-Bus client (zbus). The keyutils store was compiled in but never selected. So every 0.6 release has stored Linux secrets in the Secret Service, whatever the docs said.

The current release keeps that behaviour and changes the client library. zbus 6 folded zvariant and zbus_names into itself, which left the standalone crates that zbus 5 depends on flagged as unmaintained (RUSTSEC-2026-0370, 0371, 0372). The Secret Service stores for keyring still require zbus 5, so the crate now depends on keyring-core and the per-platform stores directly, and uses the libdbus-based Secret Service store on Linux.

Both stores look items up by the same service and username attributes, create them in the default collection with the same label, and store the secret as the same raw bytes. A secret written by any 0.6 release is read by this one, and one written by this release is read by an older one.

Why not kernel keyutils

Keyutils is pure Rust and needs no daemon, which is why the docs once described it as the hermetic default. Its entries are scoped to the session, though, and vanish at logout or reboot.

Making it the default now would also be a silent data loss. Every secret stored since 0.6.0 sits in the Secret Service; a build that switched to keyutils would stop finding them, and the only symptom would be a tool asking for credentials it already had. Keeping the backend that has actually been in use is the change that breaks nobody.

What the Secret Service costs

At run time it needs a D-Bus session bus and a running provider such as GNOME Keyring or KWallet. A desktop session has both. Headless servers, containers and CI runners usually have neither, and every keychain call fails there with CredentialError::Keychain. That was equally true of every 0.6 release.

At build time it needs a C compiler. The store links libdbus, which is compiled from source by libdbus-sys and linked statically, so the build host needs no libdbus-1-dev or pkg-config, and the binary needs no libdbus-1 where it runs. Building for a musl target needs a musl C compiler such as musl-gcc from the musl-tools package.

This is a step back from a dependency graph that compiled no C on Linux. The crate itself still forbids unsafe code; the C lives in libdbus-sys, the same way it would in any other D-Bus client that is not zbus.

What linux-persistent means now

Nothing. It used to add the libdbus store without selecting it, and now the libdbus store is always the Linux backend. The feature is kept as an empty feature so manifests that name it, including rust-tool-base's credentials-linux-persistent, keep resolving.

For servers the advice has not changed: keychain storage is usually the wrong tool there, and an environment variable is both simpler and the crate's recommended default.