Files
omarchy/plugins/io.github.elevate08.qs-bitwarden-cli/docs/ideas/ssh-approval-popup.md
T
asepharyana 1cdb82a76f Sync config from arch
- hypr/apps.lua
- hypr/autostart.lua
- hypr/envs.lua
- hypr/hyprland.lua
- hypr/hyprsunset.conf
- hypr/input.lua
- hypr/looknfeel.lua
- hypr/omasettings.lua
- hypr/xdph.conf
- omarchy/branding/about.txt
- omarchy/branding/screensaver.txt
- omarchy/extensions/omarchy-menu.jsonc
- omarchy/hooks/battery-low.d/play-warning-sound.sample
- omarchy/hooks/font-set.d/show-font-notification.sample
- omarchy/hooks/post-boot.d/weather.sample
- omarchy/hooks/post-update.d/install-voxtype.hook
- omarchy/hooks/post-update.d/setup-agent.hook
- omarchy/hooks/post-update.d/setup-fingerprint.hook
- omarchy/hooks/post-update.d/show-update-notification.sample
- omarchy/hooks/pre-refresh-pacman.d/add-custom-repo.sample
- omarchy/hooks/theme-set.d/show-theme-notification.sample
- omarchy/shell.json
- omarchy/shell.toml
- omarchy/theme.name
- omarchy/themes/azure-glow/README.md
- omarchy/themes/azure-glow/alacritty.toml
- omarchy/themes/azure-glow/btop.theme
- omarchy/themes/azure-glow/hyprland.conf
- omarchy/themes/azure-glow/hyprlock.conf
- omarchy/themes/azure-glow/icons.theme
- … 269 more
2026-09-23 15:19:12 +07:00

4.9 KiB

Spec: Centered SSH Approval Popup

Status: implementation approved by the feature request

Objective

Add an opt-in SSH authorization surface that appears in the center of the active bar output instead of opening the Bitwarden panel. A locked vault first shows a clear unlock-required state and the configured unlock controls; after unlocking, the same transient surface changes to the existing SSH signing approval. The surface disappears as soon as the request is answered, cancelled, or expires.

Tech Stack

  • QML/Qt 6 with Quickshell 0.3.1 and Omarchy 4.0.2.
  • The existing Panel root remains the owner of vault, SSH-helper, request, deadline, cooldown, and unlock state.
  • A Quickshell PanelWindow on the Wayland overlay layer presents the centered surface on the bar widget's output.
  • No new dependency or helper protocol message is introduced.

Commands

node tests/ssh-agent-setup.test.js
node tests/ssh-agent-ui.test.js
for test_file in tests/*.test.js; do node "$test_file" || exit 1; done
env -u DISPLAY -u WAYLAND_DISPLAY -u QT_QPA_PLATFORMTHEME \
  QT_QPA_PLATFORM=offscreen /usr/lib/qt6/bin/qmltestrunner -input tests/qml
mkdir -p /tmp/qs-imports
ln -sfn /usr/share/omarchy/shell /tmp/qs-imports/qs
/usr/lib/qt6/bin/qmllint -I /tmp/qs-imports Panel.qml SshApprovalPopup.qml SshApprovalScreen.qml SshUnlockScreen.qml
omarchy plugin validate .

Project Structure

  • Panel.qml: owns request routing, vault state, unlock actions, and setting values.
  • SshApprovalPopup.qml: owns only the centered window, focus, and dismissal.
  • SshApprovalScreen.qml: reusable authorization content for panel and popup.
  • SshUnlockScreen.qml: popup unlock-required status and unlock controls.
  • BitwardenModel.js / manifest.json: setting contract and safe default.
  • tests/: static integration and pure model tests; tests/qml/: QML tests.

Code Style

Keep presentation declarative and authorization imperative in Panel.qml:

SshApprovalPopup {
  panel: root
  anchorItem: button
}

All request-derived text uses Text.PlainText. Use Omarchy spacing, color, border, typography, input, and button components rather than custom values.

Testing Strategy

  • Add failing contract tests for the new setting in both manifest and model.
  • Add failing wiring tests proving popup mode does not call root.open(), the legacy mode still does, and unlock transitions reuse the same pending request.
  • Lint every new QML component against the installed Omarchy imports.
  • Run the full JavaScript and QML suites before handoff.
  • Runtime acceptance requires an enabled development plugin, a locked vault, and a real SSH signing request; no real credentials belong in tests or logs.

Boundaries

  • Always: keep the setting false by default; deny on Escape, outside click, cancellation, and timeout; render request metadata as plain text; clear transient unlock input when the popup closes.
  • Ask first: changing helper authorization, request deadlines, cooldown rules, credential storage, or the SSH control protocol.
  • Never: put session tokens, passwords, private keys, payloads, or signatures in popup-local persistent state, command arguments, logs, or fixtures.

Threat Model

  • Request key/process labels cross from a same-UID client through the helper and are untrusted display data. Plain-text rendering prevents markup from becoming UI.
  • The overlay is presentation, not an authorization boundary. Existing helper request IDs, epochs, deadlines, peer checks, and final authorization checks remain authoritative.
  • The desktop lock-state gate remains ahead of both panel and popup prompts.
  • The master password and recovered PIN/fingerprint password continue through the existing bounded private-FIFO path and are scrubbed by existing process cleanup.
  • A popup must never approve from a bare Enter key; denial is the default focused action.

Success Criteria

  • sshAgentApprovalPopup is a boolean setting, disabled by default.
  • With it disabled, SSH unlock and approval requests behave exactly as before.
  • With it enabled, an SSH request does not open or navigate the anchored panel.
  • A locked vault shows why it must be unlocked and offers configured PIN, fingerprint, and master-password paths without duplicating auth logic.
  • A successful unlock changes the same centered surface to the signing prompt, including key, fingerprint, requesting program, deadline, and grant option.
  • Deny, approve, cancellation, timeout, and outside click remove the surface; a panel the user already opened remains where it was.
  • The centered window uses the bar widget's output, stays within the output at narrow sizes, follows the Omarchy theme, and is fully keyboard operable.

Open Questions

None for implementation. Full account login remains a panel workflow; the popup is intentionally limited to a signed-in but locked vault and SSH signing authorization.