Skip to content

fix(desktop): Niri/Hyprland - Linux secret storage backend#2916

Open
mwolson wants to merge 1 commit into
pingdotgg:mainfrom
mwolson:fix/linux-secret-store-backend-v2
Open

fix(desktop): Niri/Hyprland - Linux secret storage backend#2916
mwolson wants to merge 1 commit into
pingdotgg:mainfrom
mwolson:fix/linux-secret-store-backend-v2

Conversation

@mwolson

@mwolson mwolson commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes #2880.

This selects an encrypted Linux safeStorage backend before Electron is ready, so desktop SSH environment credentials and the encrypted connection catalog can be persisted on Linux sessions Electron does not recognize automatically.

Upstream's Clerk bridge migration (#3092) moved cloud auth off safeStorage, but DesktopSavedEnvironments and DesktopConnectionCatalogStore still depend on Electron's Linux password-store backend selection.

Problem and Fix

Problem and Why it Happened Fix
Electron 41 can fall back to basic_text on Linux sessions such as Niri or unversioned KDE/Plasma because the desktop name is not one of Electron's recognized backend selectors. Resolve a Linux password-store switch before app.ready and default unknown non-KDE sessions to gnome-libsecret, while using KWallet for KDE/Plasma sessions.
The desktop app did not have a pre-ready settings path for a user-selected Linux password-store override. Read the persisted linuxPasswordStore setting synchronously during early Electron startup, with unsupported values normalized to auto without dropping unrelated settings.
AppImage sessions can start without the session bus and desktop environment variables needed by Linux secret stores. Hydrate Linux session environment values from the login shell before re-resolving the runtime password-store switch.

Defensive Fixes

Problem and Why it Happened Fix
Upstream no longer registers privileged custom protocol schemes before ready; Electron requires that registration synchronously at bootstrap. Add ElectronProtocol.layerSchemePrivileges for both t3code and t3code-dev, sequenced with pre-ready command-line switch setup before the broader desktop runtime layer can build.
Safe-storage failures were hard to diagnose on Linux. Log the configured password-store decision before ready and the selected backend after ready, without probing keyring availability during startup.

Application Startup Sequence

Before this change, main.ts built the desktop runtime directly from the Clerk layer. Linux password-store selection and privileged scheme registration did not happen before app.ready, and DesktopApp.startup only applied a WM class switch after shell hydration:

DesktopApp.program
  |
  v
desktopClerkLayer
  |
  v
desktopApplicationLayer + electronLayer + Node/HTTP services
  |
  v
DesktopApp.startup
  |
  +-- shellEnvironment.installIntoProcess
  +-- append Linux WM class switch (no password-store selection)
  +-- clerk.configure, whenReady
  +-- bootstrap

After this change, main.ts still boots through the Clerk layer, but inserts pre-ready Electron setup before DesktopApp.startup runs and extends startup with password-store re-resolution and safeStorage diagnostics:

DesktopApp.program
  |
  v
desktopClerkLayer
  |
  v
desktopApplicationRuntimeLayer
  |
  +-- desktopElectronPreReadyLayer
  |     |
  |     +-- ElectronProtocol.layerSchemePrivileges
  |     |     (register t3code + t3code-dev before ready)
  |     +-- configureElectronBeforeReady
  |           |
  |           +-- read existing --password-store
  |           +-- read early Linux settings from desktop-settings.json
  |           +-- append pre-ready command-line switches (class, password-store)
  |           +-- provide DesktopPreReadyElectronOptions
  |
  |  serial barrier: all pre-ready setup completes before broader runtime
  v
DesktopApp.startup
  |
  +-- shellEnvironment.installIntoProcess (Linux session env hydration)
  +-- re-resolve password-store if shell changed XDG_* / DBUS
  +-- clerk.configure, whenReady, safeStorage backend logging

Known Limitations

  • The first pre-ready password-store decision uses process.env before login-shell hydration. KDE/Plasma sessions that only expose XDG_* after shell hydration may get gnome-libsecret until restart unless the user passes --password-store on the command line or sets linuxPasswordStore explicitly.
  • Bugbot flagged this timing in review; the post-shell re-resolution in DesktopApp.startup covers the common AppImage case but not every desktop session ordering.

Validation

  • bun fmt
  • bun lint
  • bun typecheck
  • bun run --filter @t3tools/desktop test -- linuxSecretStorage DesktopEarlyElectronStartup DesktopAppSettings DesktopShellEnvironment DesktopSavedEnvironments
  • Rebased onto upstream main (includes Clerk bridge #3092); PR CI green at 9c0f41559

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes: N/A, desktop startup and persistence behavior
  • I included a video for animation/interaction changes: N/A- [x] I included a video for animation/interaction changes: N/A

Note

Medium Risk
Touches startup ordering, Electron CLI switches, and encrypted credential backends on Linux; wrong heuristics or timing could still mis-select storage until restart.

Overview
Fixes encrypted credential persistence on Linux desktops Electron does not recognize (e.g. Niri/Hyprland) by choosing Electron’s password-store before app.ready and again after login-shell env hydration.

Pre-ready bootstrap: Adds synchronous read of desktop-settings.json (JSONC) for linuxPasswordStore, heuristics in linuxSecretStorage (auto → KWallet on KDE/Plasma, gnome-libsecret otherwise, no override when Electron already knows the session), WM class plus optional password-store switches, and privileged t3code / t3code-dev scheme registration via a dedicated pre-ready layer in main.ts.

Runtime startup: After installIntoProcess, re-resolves password-store from updated XDG_* / DBUS (unless --password-store was passed), exposes removeCommandLineSwitch, and logs configured store plus safeStorage backend on Linux.

Settings & shell: Persists linuxPasswordStore (default auto, invalid values normalized). Linux shell hydration now pulls session/desktop/DBus vars from the login shell and can synthesize DBUS_SESSION_BUS_ADDRESS from /run/user/<uid>/bus.

Reviewed by Cursor Bugbot for commit e739ccb. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Fix Linux secret storage backend selection for Niri/Hyprland desktop environments

  • Adds pre-ready Electron configuration on Linux that reads linuxPasswordStore from desktop settings and sets the password-store command-line switch before Electron's ready event, respecting any explicit CLI override.
  • Introduces resolveLinuxPasswordStoreSwitch in linuxSecretStorage.ts to map user preference and desktop session environment (XDG hints) to the correct Electron switch value, with fallback guidance for GNOME Keyring vs KWallet.
  • Expands installPosixEnvironment in DesktopShellEnvironment.ts to import desktop session hints (XDG_CURRENT_DESKTOP, XDG_SESSION_TYPE, WAYLAND_DISPLAY, etc.) from the login shell and auto-discover DBUS_SESSION_BUS_ADDRESS when unset.
  • Adds linuxPasswordStore to DesktopSettings with normalization on load and persistence when changed from the default.
  • Extends ElectronSafeStorage with selectedStorageBackend (Linux-only) and ElectronApp with removeCommandLineSwitch to support runtime switch management.
  • Behavioral Change: the password-store switch is now cleared and re-set on each startup based on settings and environment, rather than left to Electron's default heuristics.

Macroscope summarized e739ccb.

@coderabbitai

coderabbitai Bot commented Jun 2, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 348ae9fe-8a07-4ea0-a72f-252e8aca7297

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Jun 2, 2026
Comment thread apps/desktop/src/app/DesktopApp.ts
@macroscopeapp

macroscopeapp Bot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces new Linux desktop environment detection logic and secret storage backend configuration, affecting application startup behavior. While framed as a fix, the scope includes new heuristics, new settings, and new command-line manipulation - constituting a new feature rather than a simple bug fix.

You can customize Macroscope's approvability policy. Learn more.

@mwolson mwolson marked this pull request as draft June 3, 2026 01:56
@mwolson mwolson force-pushed the fix/linux-secret-store-backend-v2 branch 3 times, most recently from 1ec83f0 to 57dcaa9 Compare June 3, 2026 14:00
@mwolson mwolson marked this pull request as ready for review June 3, 2026 14:37
@mwolson mwolson force-pushed the fix/linux-secret-store-backend-v2 branch from 57dcaa9 to 9bf124e Compare June 3, 2026 14:41
Comment thread apps/desktop/src/main.ts Outdated
@mwolson mwolson marked this pull request as draft June 3, 2026 14:57
@mwolson mwolson force-pushed the fix/linux-secret-store-backend-v2 branch 7 times, most recently from c4ee8d6 to 5f02a0e Compare June 3, 2026 17:33
@mwolson mwolson marked this pull request as ready for review June 3, 2026 17:58
@mwolson mwolson force-pushed the fix/linux-secret-store-backend-v2 branch from 5f02a0e to a8ab180 Compare June 3, 2026 18:02
@juliusmarminge juliusmarminge force-pushed the fix/linux-secret-store-backend-v2 branch from a8ab180 to f38b824 Compare June 4, 2026 00:57
@mwolson mwolson force-pushed the fix/linux-secret-store-backend-v2 branch 4 times, most recently from f9c8c69 to 219f76d Compare June 11, 2026 13:35
@mwolson mwolson force-pushed the fix/linux-secret-store-backend-v2 branch from 219f76d to 7704609 Compare June 12, 2026 02:10
Comment thread apps/desktop/src/app/DesktopEarlyElectronStartup.ts
@mwolson mwolson force-pushed the fix/linux-secret-store-backend-v2 branch 2 times, most recently from 61c6919 to 4b49244 Compare June 16, 2026 23:41
@mwolson mwolson changed the title fix(desktop): Select Linux secret storage backend fix(desktop): Niri - Linux secret storage backend Jun 17, 2026
@mwolson mwolson force-pushed the fix/linux-secret-store-backend-v2 branch 5 times, most recently from d760719 to 0733d82 Compare June 19, 2026 03:44
@mwolson mwolson changed the title fix(desktop): Niri - Linux secret storage backend fix(desktop): Niri/Hyprland - Linux secret storage backend Jun 20, 2026
@mwolson mwolson force-pushed the fix/linux-secret-store-backend-v2 branch from 0733d82 to 9c0f415 Compare June 20, 2026 02:03
@github-actions github-actions Bot added size:XL 500-999 changed lines (additions + deletions). and removed size:L 100-499 changed lines (additions + deletions). labels Jun 20, 2026
@mwolson mwolson force-pushed the fix/linux-secret-store-backend-v2 branch from 9c0f415 to 7daa03d Compare June 21, 2026 20:25
@github-actions github-actions Bot added size:L 100-499 changed lines (additions + deletions). and removed size:XL 500-999 changed lines (additions + deletions). labels Jun 21, 2026
Comment thread apps/desktop/src/shell/DesktopShellEnvironment.ts Outdated
Comment thread apps/desktop/src/shell/DesktopShellEnvironment.ts
Comment thread apps/desktop/src/app/DesktopApp.ts

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Effect Service Conventions: one finding — a standalone service-shape interface was introduced for a new Context.Service. See inline comment.

Posted via Macroscope — Effect Service Conventions

Comment thread apps/desktop/src/app/DesktopPreReadyPlatform.ts
@github-actions github-actions Bot added size:XL 500-999 changed lines (additions + deletions). and removed size:L 100-499 changed lines (additions + deletions). labels Jun 21, 2026
@mwolson mwolson force-pushed the fix/linux-secret-store-backend-v2 branch 4 times, most recently from 9b75d1c to e030be2 Compare June 21, 2026 21:37
Comment thread apps/desktop/src/shell/DesktopShellEnvironment.ts
Comment thread apps/desktop/src/linuxSecretStorage.ts
@mwolson mwolson force-pushed the fix/linux-secret-store-backend-v2 branch from e030be2 to dde3435 Compare June 21, 2026 23:04

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit dde3435. Configure here.

Comment thread apps/desktop/src/linuxSecretStorage.ts
Address Bugbot review: authoritative desktop hints and shell DBUS override
@mwolson mwolson force-pushed the fix/linux-secret-store-backend-v2 branch from dde3435 to e739ccb Compare June 21, 2026 23:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL 500-999 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]:Linux/Hyprland: SSH environment setup fails because Electron safeStorage reports encryption unavailable

1 participant