Skip to content

fix(linux): detect Secret Service via D-Bus to prevent basic_text fallback#1908

Closed
krit22 wants to merge 2 commits intogeneralaction:mainfrom
krit22:fix/linux-safe-storage-v2
Closed

fix(linux): detect Secret Service via D-Bus to prevent basic_text fallback#1908
krit22 wants to merge 2 commits intogeneralaction:mainfrom
krit22:fix/linux-safe-storage-v2

Conversation

@krit22
Copy link
Copy Markdown

@krit22 krit22 commented May 6, 2026

Fixes #1875.

Summary

Chromium picks its keyring backend by inspecting XDG_CURRENT_DESKTOP. It only recognises a hardcoded set of values (GNOME, XFCE, unity, etc.), so modern compositors like Hyprland, sway, i3, and dwm cause it to silently fall back to basic_text — even when gnome-keyring is fully operational on the session bus. Emdash's assertSecureStorageAvailable then correctly rejects basic_text, making the app unusable.

This fix probes org.freedesktop.secrets on the session bus via dbus-send before Chromium initialises. If the Secret Service is present, it appends --password-store=gnome-libsecret to Chromium's command line — the upstream-supported way to guide backend selection.

Three guards prevent over-reaching:

  • Skips if no Secret Service is found on D-Bus (fail safe)
  • Skips if XDG_CURRENT_DESKTOP contains kde (Chromium handles KWallet natively)
  • Skips if the user already passed --password-store= manually

Test plan

Reproduced on Kali Linux (XFCE) with XDG_CURRENT_DESKTOP=Hyprland:

Before — sign-in throws immediately:

Failed to store session token: Error: Secure secret storage is unavailable on this system.
    at EncryptedAppSecretsStore.assertSecureStorageAvailable

After — sign-in completes, token persists across restarts.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 6, 2026

Greptile Summary

This PR fixes startup failures on Linux desktops with modern compositors (Hyprland, sway, i3, etc.) by probing org.freedesktop.secrets on the D-Bus session bus before Chromium initialises, then appending --password-store=gnome-libsecret when the Secret Service is present and Chromium's XDG_CURRENT_DESKTOP-based detection would otherwise fall back to basic_text.

  • A synchronous secretServiceAvailable() helper is called at module load time \u2014 before app.isReady() \u2014 which is the correct window for setting Chromium command-line switches; KDE and user-supplied --password-store= overrides are guarded against.
  • The --print-reply=literal flag strips D-Bus type annotations so the output should be exactly \"true\" or \"false\"; the current output.includes('true') substring check works in practice but a strict === 'true' comparison would be more precise.
  • Open concerns from prior threads (no timeout on execFileSync, and Plasma-branded KDE sessions bypassing the kde guard) remain unaddressed in the current diff.

Confidence Score: 4/5

The fix is logically sound but two robustness concerns from prior review threads remain unaddressed in the current code.

The D-Bus probe and conditional flag injection are correctly placed before app.isReady(), and the try/catch makes detection fail-safe. What holds the score back is that execFileSync is called without a timeout — a sluggish D-Bus daemon could hang the Electron main process indefinitely at startup — and XDG_CURRENT_DESKTOP values like 'Plasma' (KDE without the 'kde' token) still bypass the KDE guard and would inject gnome-libsecret into a KWallet session.

src/main/index.ts — the secretServiceAvailable() function and the surrounding Linux conditional block

Important Files Changed

Filename Overview
src/main/index.ts Adds synchronous D-Bus probe at module load to detect Secret Service and conditionally append --password-store=gnome-libsecret; KDE and user-override guards are present but the Plasma-without-KDE edge case remains an open concern from prior review threads.

Sequence Diagram

sequenceDiagram
    participant M as Main Process (index.ts)
    participant D as dbus-send
    participant DB as D-Bus Session Bus
    participant C as Chromium (app.commandLine)

    M->>M: module load (platform === linux)
    M->>D: execFileSync dbus-send NameHasOwner org.freedesktop.secrets
    D->>DB: org.freedesktop.DBus.NameHasOwner
    DB-->>D: boolean true or false
    D-->>M: stdout true or false
    alt Secret Service found AND not KDE AND no user override
        M->>C: appendSwitch password-store gnome-libsecret
    else No Secret Service or KDE or user override
        M->>M: skip default backend
    end
    M->>M: registerAppScheme app lifecycle continues
Loading
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
src/main/index.ts:47
Using `.includes('true')` is a substring match — technically, any output containing the word "true" (e.g. a hypothetical diagnostic message) would be a false positive. After `.trim()`, `dbus-send --print-reply=literal` outputs exactly `"true"` or `"false"` for this boolean method, so a strict equality check is both more correct and self-documenting.

```suggestion
    return output === 'true';
```

Reviews (2): Last reviewed commit: "Merge branch 'main' into fix/linux-safe-..." | Re-trigger Greptile

Comment thread src/main/index.ts
Comment thread src/main/index.ts
@krit22 krit22 closed this May 6, 2026
@krit22 krit22 reopened this May 6, 2026
@krit22 krit22 closed this May 6, 2026
@krit22 krit22 reopened this May 6, 2026
@krit22 krit22 closed this May 7, 2026
@krit22 krit22 deleted the fix/linux-safe-storage-v2 branch May 7, 2026 06:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Linux: safeStorage falls back to basic_text on non-GNOME/KDE desktops, breaking all credential storage

1 participant