Native credential backends
The keychain feature uses keyring-core directly. Implementations live in
crates/identity/src/auth/keychain/; bootstrap::keychain supplies the shared
adapter to server construction and the credential CLI. The existing identity
singleton retains breadcrumb deduplication for vendor credential resolution.
Each adapter owns its store rather than using keyring-core’s mutable process
default. The first credential operation initializes the real store; startup
that uses only environment/file/provider credentials needs no desktop agent.
Initialization errors are cached and returned as KeychainError::Unavailable;
restart after restoring the native service. No mock or sample store is selected
in production. Operation errors remain errors, with fixed diagnostic categories
instead of provider payloads or credential objects.
Selected versions and upstream APIs
Section titled “Selected versions and upstream APIs”Verified on 2026-10-19; the Rust baseline remains 1.99.0. Registry dependencies are exact-pinned in the identity manifest.
| Dependency | Pin | Selection/API |
|---|---|---|
| keyring-core | =1.0.1 |
Store-owned CredentialStoreApi::build(service, user, None) and Entry get/set/delete; no global default or sample feature |
| dbus-secret-service-keyring-store | =1.0.1 |
Linux Store::new(), crypto-rust and vendored; upstream connects using EncryptionType::Dh, never a plaintext session |
| apple-native-keyring-store | =1.0.2 |
macOS keychain::Store::new(), keychain feature, preserving Keychain Services rather than switching to protected-data storage |
| windows-native-keyring-store | =1.1.0 |
Windows Store::new(), default target-name mapping/persistence preserved; unused search feature disabled |
The prior keyring = 4.2.0 v1 compatibility wrapper selected
zbus-secret-service-keyring-store = 1.0.0 on Linux. The explicit keyutils
feature in our former manifest did not change that selection. No migration
from kernel keyutils storage is needed for credentials written by that wrapper.
The product lockfile drops keyring, both old Linux stores, secret-service,
zbus, zbus_macros, zbus_names, zvariant, zvariant_derive,
zvariant_utils, and dependencies used only by that chain. It adds dbus 0.9.12,
dbus-secret-service 4.1.0, and libdbus-sys 0.2.7. Cargo also records optional
OpenSSL packages due to the upstream optional vendoring feature; they are not
activated by our crypto-rust selection (cargo tree -i openssl has no active
path). This migration upgrades no unrelated existing package versions. All deny.toml
duplicate exceptions are still matched and required by the remaining graph;
none became obsolete. Advisory ignores remain empty.
Credential compatibility
Section titled “Credential compatibility”Service names remain mcp-server-devtools.<kind>.<vendor>, and accounts remain
the original principal string. A missing current entry falls back to
mcp-server-atlassian.<kind>.<vendor>; an error does not. Writes update only the
current namespace. Removal attempts both namespaces, returns NotFound only
when neither exists, and propagates errors. Linux stores search all collections
by the same service and username attributes with no target modifier. Existing
ambiguity remains an error; the adapter does not arbitrarily choose or delete a
credential when several items match.
Run the compatibility check on Linux with a GNOME keyring daemon and D-Bus tools:
scripts/ci/keychain-compatibility.shThe script builds the former v1 writer in a temporary project outside the
product graph, with keyring 4.2.0, keyring-core 1.0.0, zbus store 1.0.0,
secret-service 5.1.0 and zbus 5.19.0. It uses a private session bus, a temporary
home/config/data/runtime directory, and a synthetic unlock password. It writes
24 synthetic entries across two secret kinds, three vendors, current-only,
legacy-only and both-namespace cases. The new identity adapter reads/deletes
these, exercises new write/update/delete operations, and the old writer then
confirms all 24 entries are gone. It never uses the user’s bus or personal
keyring. GNOME_KEYRING_DAEMON can select an unpacked test daemon. The live Rust
test is ignored by ordinary runs and requires the script’s isolation marker.
Ordinary tests cover keychain-disabled operations, a genuinely unavailable native backend in a child process (even with a global mock installed), namespace precedence/isolation, error propagation, diagnostic redaction and removal of the deprecated dependencies. Injected mock stores exist only in unit-test code.
Static packaging and maintenance
Section titled “Static packaging and maintenance”vendored statically links libdbus, avoiding a runtime dependency on the host’s
libdbus shared library and the old CI requirement for libsecret/libdbus headers.
It requires a C compiler. It does not make a GNU/Linux executable wholly
static; libc linkage still follows the selected Rust target. It also does not
bundle a running D-Bus daemon or a Secret Service: desktop runtime prerequisites
remain an available session bus, Secret Service and an unlocked collection.
The existing musl/distroless image and system packages disable keychain, so
neither libdbus nor an OS keyring agent enters those artifacts.
The locked libdbus-sys 0.2.7 bundles D-Bus 1.14.4 C sources. This adds native
code/FFI and means operating-system library updates do not patch the bundled
copy; monitor upstream C security fixes and rebuild the binary when updating.
A clean RustSec gate is not a complete advisory audit of those embedded sources.
The bundled library’s AFL-2.1 license option and source location are recorded in
NOTICE, docs/licensing.md, and licenses/libdbus-COPYING.txt; the existing
archive workflow includes these files. The Rust wrapper’s MIT/Apache metadata
alone is not the C library’s license.
Validation record
Section titled “Validation record”Validated on Linux on 2026-10-19 with Rust 1.99.0, the shared repository target, debug information disabled for dev/test and incremental compilation disabled:
- Focused identity tests and Clippy with keychain enabled and disabled passed; root authentication and credential CLI tests passed (63 tests).
- The isolated GNOME Secret Service compatibility script passed: all 24 old
entries were read and deleted, the previous backend confirmed their removal,
and new write/update/delete operations passed. A bus monitor restricted to
OpenSessionobserved encrypted DH/AES session negotiation and noplainsessions. No personal credentials or desktop bus were used. - Workspace default and headless builds and Clippy (
--all-targets -- -D warnings) passed. Default and Cedar workspace test suites passed; Cedar build and Clippy also passed. Formatting andcargo deny --locked check --deny warningspassed without advisory suppression or duplicate exceptions added. - The first default test run hit the console’s existing one-second expiry test; an additional serial run hit the response-cache principal-partitioning test. Both tests passed individually, and a subsequent normal full default suite passed. Neither test nor its implementation was changed for this migration.
- The actual identity keychain adapter and contracts compiled for
x86_64-apple-darwin,aarch64-apple-darwinandx86_64-pc-windows-msvcin a temporary harness using the product’s exact dependency versions. Full native product linking, macOS/Windows credential runtime tests and native installers remain unverified on this Linux host. - Debian/RPM package assembly and installation remain unverified: this host lacks the pinned package tools and the rootless systemd/Podman test runtime.
- ELF inspection of the Linux live-test binary confirmed no shared libdbus or OpenSSL dependency. The bundled C library still requires separate upstream security monitoring as described above.
- The repository Dockerfile built the keychain-disabled x86_64 musl release
image successfully. In its distroless runtime, with networking disabled and
a read-only root filesystem,
--versionreported0.18.0and a syntheticcreds getreturned the expected keychain-unavailable error. The extracted binary is a static PIE with no ELF interpreter. This was local validation; no image was published or deployed. The image’s live Vault round-trip was not exercised.
These repository gates use the keyring migration snapshot with
async-compression 0.4.50. The concurrent upgrade to 0.4.51 is being validated
separately by its owning task. Live Keycloak/Vault/SIEM, cloud-account and
rootless systemd operations scenarios were not exercised by these ordinary
workspace runs. Security review found no high-confidence introduced
vulnerability; MCP01 and MCP04 controls and residual risks are recorded in the
OWASP assessment, threat model and best-practices map.