Skip to content

fix(vault): wire OS keyring (libsecret/Keychain/Credential Manager)#3180

Merged
houko merged 1 commit into
mainfrom
fix/issue-3178-os-keyring
Apr 25, 2026
Merged

fix(vault): wire OS keyring (libsecret/Keychain/Credential Manager)#3180
houko merged 1 commit into
mainfrom
fix/issue-3178-os-keyring

Conversation

@houko

@houko houko commented Apr 25, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes #3178.

The vault docs (docs/src/app/security/network-api/page.mdx, docs/src/app/architecture/security/page.mdx) promised:

The vault uses AES-256-GCM encryption with a master key stored in the OS keyring (macOS Keychain / Windows Credential Manager / Linux Secret Service)…

But store_keyring_key / load_keyring_key in vault.rs only ever exercised the file-based AES-256-GCM fallback path. Every librefang init on Linux printed:

WARN OS keyring unavailable — falling back to file-based key storage at "/home/.../.keyring".

…even when gnome-keyring + libsecret were running fine. Contradicts the docs; unnerving for security-conscious users.

The previous developer had even reserved a KEYRING_USER = "master-key" constant gated under #[allow(dead_code)] — the rest of the OS-keyring wiring just never landed.

Fix

  • Add keyring = { version = "3", features = ["apple-native", "windows-native", "sync-secret-service"] } to the workspace and to librefang-extensions. Covers macOS Keychain, Windows Credential Manager, and libsecret-based Linux Secret Service implementations.
  • store_keyring_key: try keyring::Entry::set_password first; only fall back to the file-based wrapped store on failure. The existing WARN OS keyring unavailable line is now scoped to that real-fallback path so it no longer fires on healthy hosts.
  • load_keyring_key: try keyring::Entry::get_password first. NoEntry drops through silently to the file path so existing installs that previously wrote a fallback keep loading without WARN noise; other errors are debug!-logged and the file path is tried as a last resort.

Test plan

  • Manual on macOS: fresh librefang init → no fallback WARN → master key visible in Keychain Access under service librefang-vault, account master-key. Subsequent runs unlock vault from Keychain.
  • Manual on Linux with gnome-keyring: fresh librefang init → no fallback WARN → key visible via secret-tool lookup service librefang-vault username master-key. Headless install without Secret Service still falls back to file with the existing WARN.
  • Manual on Linux without Secret Service (e.g. unset DBUS_SESSION_BUS_ADDRESS): WARN still fires, file fallback works.
  • Migration: existing install with file-based keyring → upgrade → load still succeeds via file fallback (NoEntry on OS keyring, then file path).
  • CI green

…3178)

The vault docs promised "OS keyring (macOS Keychain / Windows Credential
Manager / Linux Secret Service)" support but store_keyring_key /
load_keyring_key only ever exercised the file-based AES-256-GCM
fallback. Every `librefang init` on Linux therefore printed
"OS keyring unavailable" even when gnome-keyring + libsecret were
running fine, contradicting the documentation and unnerving users.

The previous developer had even reserved a KEYRING_USER constant for
this — the rest of the wiring just never landed.

This commit lights up the keyring crate (apple-native /
windows-native / sync-secret-service features) and restructures both
sides:

- store_keyring_key tries keyring::Entry::set_password first; only
  falls back to the file-based wrapped store on failure (with the
  existing WARN scoped to that real-fallback path).
- load_keyring_key tries keyring::Entry::get_password first;
  NoEntry drops through silently to the file path so existing
  installs that already wrote a fallback keep loading; other errors
  are debug-logged and the file path is tried as a last resort.

Closes #3178.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@houko
houko merged commit 42fd29b into main Apr 25, 2026
21 of 22 checks passed
@houko
houko deleted the fix/issue-3178-os-keyring branch April 25, 2026 16:45
@github-actions github-actions Bot added area/security Security systems and auditing ready-for-review PR is ready for maintainer review size/M 50-249 lines changed and removed ready-for-review PR is ready for maintainer review labels Apr 25, 2026
houko added a commit that referenced this pull request Apr 27, 2026
* fix(release): install libdbus-1-dev for glibc Linux CLI builds

Beta 6 shipped without all 10 Linux CLI assets because the keyring crate
(wired in #3180) pulls libdbus-sys transitively on glibc Linux, but the
release workflow only apt-installed pkg-config + libssl-dev.

#3265 patched the Dockerfile and #3267 made keyring target-conditional
(unblocking musl + android), but release.yml + Cross.toml were never
updated, so the four glibc CLI tarballs would still fail on the next
release.

Adds libdbus-1-dev to:
- cli_linux job (x86_64 native build)
- cli_linux_mini job (x86_64 native build)
- Cross.toml aarch64-unknown-linux-gnu pre-build (cross sysroot)

* fix(release): install libdbus-1-dev for desktop Linux build too

Same root cause as the CLI fix in this PR — `librefang-desktop`
depends on `librefang-extensions`, which on glibc Linux pulls the
keyring crate -> libdbus-sys, which needs libdbus-1-dev at link
time. The desktop linux job has been getting away with it because
webkit2gtk transitively pulls libdbus-1-dev today, but relying on
that is brittle: an apt metadata change on the runner image could
silently break the desktop linux release.

Make it explicit alongside the CLI deps already added in this PR.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/security Security systems and auditing size/M 50-249 lines changed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Librefang init is reporting missing keyring without attempting to detect it

1 participant