NewPassbox is here: on the web, desktop, iPhone, Android and your own server. Free for families.Passbox is here · See all apps
Skip to content

Using Passbox

Desktop app

Windows, macOS and Linux: locking, clipboard, tray and global shortcut.

The Passbox desktop app for Windows, macOS and Linux is a Tauri 2 shell around the web client of passboxnet/web: the window shows the web vault's build (app/dist in a checkout of passboxnet/web next to this repository), so the vault UI, the WebAssembly core and therefore all cryptography are exactly the same as in the browser. The Rust crate in src-tauri only adds desktop integration and contains no cryptographic code.

The vault itself (languages, Emergency Kit, trash, security check, devices and so on) is described in web.md. The desktop app reports itself as "Passbox Desktop on …" in the device list.

Features

FeatureHow
Server of your choiceOn first start the app asks for the server address (stored in localStorage as passbox.server). It can be changed on the sign-in screen under "Advanced" → "Use a different server" while signed out; plain http is only accepted for this computer. The server must allow cross-origin requests, which passbox-server does (see self-hosting.md).
WindowTitle "Passbox", 1200 × 780 by default, at least 720 × 520. Size, position and maximized state are restored on the next start (tauri-plugin-window-state). The web client draws the Passbox Marina vault window (glass columns on the app canvas, see design/system.md).
Window materialWindows 11: the window is transparent with the Mica material (src-tauri/tauri.windows.conf.json, merged over tauri.conf.json on Windows); the web client detects Windows 11 (applyWindowMaterial in app/src/desktop.ts of passboxnet/web) and lets Mica show through the canvas while text stays on (nearly) solid surfaces. Windows 10, macOS and Linux get the solid canvas: macOS vibrancy would need Tauri's private macOS API (macOSPrivateApi), which we do not enable. Before the page loads, the window background is the dark Marina canvas (#0C1920).
Tray iconThe app icon with a menu: Open Passbox, Lock vault and Quit Passbox (German: „Passbox öffnen“, „Tresor sperren“, „Passbox beenden“). The labels follow the web client's language (set_tray_labels). Left click opens the window on Windows and macOS. Closing the window keeps Passbox running in the tray; quit from the tray menu.
Single instanceStarting Passbox again focuses the running window (tauri-plugin-single-instance).
Global shortcutCtrl+Shift+Space (Cmd+Shift+Space on macOS) shows the window and opens the command palette. If the vault has to lock first (see below), it shows the unlock screen instead. If another app owns the shortcut, Passbox starts without it.
Lock on close, sleep and screen lockSee below.
Auto-lockThe web client's inactivity timer (Settings → Security) applies as in the browser. While the window is hidden the shell enforces it as well, because hidden webviews throttle timers.
ClipboardCopied secrets are cleared after the delay set in Settings → Security, also while the window is hidden, and when the vault locks or Passbox quits. They are marked to stay out of clipboard history. See below.

Locking

The shell sends a passbox://lock event and the web client calls client.lock(), which removes all keys and decrypted data from memory, and answers with the vault_locked command. Every lock also clears a copied secret from the clipboard. This happens on:

  • Tray menu → Lock vault, on every platform.
  • Closing the window, when Lock when the window is closed is on (Settings → Security, desktop app only, on by default).
  • Showing the window again (global shortcut, tray, starting Passbox again, Dock icon) after it was closed with that setting on, or after it was hidden for longer than the auto-lock time. The shell then sends the lock first and shows the window only after vault_locked arrives, so it appears with the unlock screen (after 2 seconds without an answer it shows the window anyway). The shell also locks by itself as soon as the hidden time exceeds the auto-lock time. The web client passes both settings with set_lock_settings; until it does, lock on close is on.
  • Sleep and hibernation, on every platform. A background thread wakes every 5 seconds; threads do not run while the computer is suspended, so a jump of the wall clock by more than 35 seconds means the computer slept. (Setting the clock forward also locks, which is harmless.) The lock happens right after waking, before anyone can use the window.
  • Screen lock and suspend on Linux, through D-Bus: ActiveChanged(true) of the screen saver interfaces of GNOME, KDE (org.freedesktop.ScreenSaver), Cinnamon and MATE on the session bus, and Session.Lock and PrepareForSleep(true) from systemd-logind on the system bus.
  • Screen lock and suspend on Windows: a hidden window registered with WTSRegisterSessionNotification receives WM_WTSSESSION_CHANGE with WTS_SESSION_LOCK (Win+L, lock screen, switching users), and WM_POWERBROADCAST with PBT_APMSUSPEND before the computer sleeps.
  • Screen lock, sleep and user switching on macOS: the distributed notification com.apple.screenIsLocked, and NSWorkspaceWillSleepNotification and NSWorkspaceSessionDidResignActiveNotification.

The Windows and macOS watchers use native FFI. The desktop crate therefore denies unsafe (instead of forbidding it like the other Passbox crates) and allows it only in those two modules of src-tauri/src/lock_watch.rs.

In the web client (browser and desktop), the auto-lock timer also re-checks the inactivity time immediately on visibilitychange, focus and pageshow, and before an interaction counts as activity, so a vault that expired while the page was hidden or the computer slept locks before it can be used.

Clipboard

In browsers the web client cannot read the clipboard without a permission prompt, and may only write to it while the page has focus. It therefore remembers the secret it copied and writes an empty string when the delay is over, unless text was copied or cut in the page since. If the page is in the background then, clearing waits for the next focus or visibilitychange; the toast says so. Locking clears right away (or as soon as the page has focus again).

In the desktop app the web client copies through the shell (clipboard_copy, clipboard_clear), which uses arboard in Rust. The shell clears the clipboard after the delay if it still holds the copied secret, also while the window is hidden, and on every lock and on quit. The secret is marked so clipboard history tools skip it:

PlatformMarker
WindowsExcludeClipboardContentFromMonitorProcessing: not in clipboard history (Win+V), not synced to the cloud clipboard, ignored by clipboard monitors
macOSorg.nspasteboard.ConcealedType (nspasteboard.org), honored by most clipboard managers
Linuxx-kde-passwordManagerHint, honored by KDE Klipper and most other clipboard managers

Bridge to the web client

app/src/desktop.ts in passboxnet/web is the only place in the web client that knows about the desktop app. It detects Tauri with "__TAURI_INTERNALS__" in window, loads @tauri-apps/api lazily, and is a no-op in browsers. Events:

EventSent whenWeb client
passbox://lockTray "Lock", closing or reopening the window (see above), sleep, screen lockclient.lock(), then vault_locked
passbox://command-paletteGlobal shortcutOpens the command palette (when unlocked)

Commands the web client calls:

CommandArgumentsPurpose
clipboard_copytext, clearAfterSecsCopies a secret and clears it later
clipboard_clearnoneClears a copied secret now (the web client calls it whenever the vault locks)
vault_lockednoneConfirms a lock request; shows a window that waits for it
set_lock_settingslockOnClose, autoLockMinutesLock settings for the hidden window
set_tray_labelsopen, lock, quitTray menu labels in the app's language (trimmed, at most 60 characters each)

The desktop app does not import the web client's code: it only references its build output (frontendDist) and its dev server (devUrl).

Security

  • Content Security Policy (tauri.conf.json): scripts only from the app itself plus 'wasm-unsafe-eval' for the WebAssembly core, no remote scripts, no frames, workers, objects or form targets. Fonts and images come from the app or data: URIs (Vite inlines small files). connect-src allows https:, http://localhost:* and http://127.0.0.1:*, because the server is chosen at runtime and cannot be listed statically. Plain http:// servers on other hosts are rejected by the app. style-src allows inline styles (React style attributes); Tauri is told not to add nonces to style-src, which would disable that.
  • Capabilities (src-tauri/capabilities/main.json): the page may listen to events (core:event:allow-listen, core:event:allow-unlisten) and call the app commands above (allow-clipboard-copy, allow-clipboard-clear, allow-vault-locked, allow-set-lock-settings, allow-agent-request-attention, allow-breach-notify, allow-set-tray-labels). build.rs declares the commands in the app manifest, so any other command is denied; the generated permission files in src-tauri/permissions/autogenerated are not checked in. Tray, shortcut and window state are handled in Rust and not exposed to JavaScript. Remote pages get no capabilities at all.
  • Session tokens stay in memory as in the browser; the account (email, Secret Key, KDF parameters) is stored in the webview's localStorage, like in the browser.