--- schemaVersion: 0 id: NL-SPEC-8EQ0TRBZ type: spec title: Nuguland vault widget --- # Nuguland vault widget ## Outcome A Nuguland bar widget provides the small daily Vaultwarden surface Oliver needs: search, inspect, reveal, copy, open, favorite, and use TOTP codes without opening a full vault client. The widget follows the [Nuguland popup interaction language](../NL-SPEC-38AED50A-popup-interaction-language/index.md). ## Behavior - Activating the vault widget opens a split popout with search and results on the left and the selected item's details on the right. - Search covers the vault's useful item metadata and updates results while typing. - Keyboard and pointer input can search, move selection, activate actions, and dismiss the popout. - A global Niri shortcut opens the popout from any workspace and focuses search. - When a browser is focused, exact origin matches are promoted using its locally observed address; a manual query remains authoritative. - Context shortcuts copy the selected item's username, password, current TOTP, or next TOTP when available. - Successful copies provide transient field-specific feedback without displaying the copied value. - Favorites appear in a distinct group before all other matching items. - An item can be favorited or unfavorited from its detail view. - Closing and reopening restores the query, selected item, result scroll position, detail scroll position, expanded sections, and reveal state. - Retained state survives popout closure, not vault locking or shell termination. - Loading, empty, locked, authentication-failure, sync-failure, stale-cache, and unavailable-vault states are explicit and actionable. - Opening requests a sync without blocking usable encrypted cached data during network loss. ## Unlock and configuration - One named profile selects the server URL, account identifier, and nonsecret behavior settings. - First use shows a calendar-style setup form for server URL and account; neither has a hardcoded default. - The settings action locks the vault before editing; cancel leaves the saved profile unchanged. - Saving validates the profile in the native boundary before persisting nonsecret JSON through Quickshell. - Changing server or account clears retained state and selects separate encrypted-cache, credential-storage, and favicon namespaces. - The required deployment targets `https://vault.bugabinga.net`; the same profile shape also targets official Bitwarden. - Credentials, tokens, master passwords, and derived keys are never configuration values. - Locking, suspend, and restart clear decrypted keys and in-memory access tokens, not the saved server login. - Refresh credentials and account-bound wrapped unlock material persist only in Secret Service. - A saved login unlocks locally with the master password, then syncs using refreshed access credentials without repeating email verification. - A missing cache can be rebuilt from the saved login without repeating second-factor authentication. - Transport failures preserve the saved login and usable cached data; definitive refresh rejection clears the saved login and locks the vault until interactive reauthentication. - Refreshed credentials are persisted before their access token is used; missing or unavailable protected storage is never replaced by plaintext storage. - Locked state shows only profile identity, cache freshness, and an in-widget master-password field. - Submitting sends the master password once to the isolated native vault boundary, then immediately clears the field. - The master password is never retained as UI state; only derived keys survive until timeout or lock. - Invalid input is cleared before another attempt. - Server-required login and second-factor challenges remain inside the locked flow and never expose vault metadata. - Closing the popout hides, rather than cancels, authentication; the challenge, selected method, and unsubmitted verification-code draft survive reopening in memory. - Closing still clears master-password and re-prompt inputs; explicit cancel, lock, timeout, suspend, and shell exit clear the pending authentication state. - Selecting email verification shows an inline inbox instruction and focuses the code field; it does not claim email delivery confirmation. - Submitting a verification code clears its draft immediately and shows a pending state until the native response arrives. The local `Quickshell.statePath("vault.json")` file uses this nonsecret profile shape. This example is not a default: ```json { "name": "personal", "serverUrl": "https://vault.example.com", "account": "user@example.com", "unlockTimeoutSeconds": 900, "clipboardTimeoutSeconds": 30 } ``` `serverUrl` accepts HTTPS Vaultwarden deployments or `https://vault.bitwarden.com` for official Bitwarden. Timeout values are seconds. ## Item details - Every item type returned by Vaultwarden is usable, including login, secure note, card, identity, and SSH key items. - Standard and custom fields are shown with their names, values, sensitivity, and applicable actions intact. - Textual values can be copied. - Sensitive values are concealed by default and have separate reveal and copy actions. - URL values can be opened through the desktop portal or copied. - Attachments and unsupported field actions are identified without hiding the rest of the item. - URL-bearing items use a cached favicon; absent or failed favicons fall back to an item-type icon. - Icon-only actions have tooltips, accessible names, and visible hover, press, and keyboard-focus states. ## TOTP - Items with TOTP show the current code, next code, and remaining time. - Clicking either code copies that displayed code. - At rollover, current and next advance together without changing selection or focus. - Items without TOTP omit the TOTP region. ## Constraints - Vault content is read-only except for favorite state. - Vault access runs through a process-isolated native Rust boundary owned by Nuguland. - The unforked official Bitwarden Rust SDK supplies cryptography and reusable models/APIs, subject to this spec's security and behavior constraints. - Nuguland's native boundary implements only missing request/response handling required by this spec; item metadata must not be silently discarded. - `rbw` is reference material, including [PR #319](https://github.com/doy/rbw/pull/319), not a library dependency or maintained fork. - Nuguland-written cryptographic implementations remain forbidden. - Desktop integration uses native Wayland, Linux, and Quickshell APIs; X11 and Xwayland are not dependencies. - Node runtimes, `bw` and `rbw` CLI executables, `rbw-agent`, browser extensions, and persistent standalone daemons are not runtime dependencies. - Quickshell owns presentation and retained navigation state; the native boundary owns authentication, cryptography, sync, encrypted cache, and browser-context inspection. - Creating, editing, deleting, sharing, autofill, password generation, and vault administration are outside scope. - Configured Vaultwarden or Bitwarden account and lock boundaries remain authoritative. - Locked state exposes no item metadata or secrets. - Master passwords never enter process arguments, environment variables, logs, retained properties, or persistent storage. - Decrypted values, retained UI state, search terms, and copied secrets are never logged or persisted to disk. - Persistent cache contains only Bitwarden-encrypted vault payloads; authentication material uses protected credential storage. - Explicit copies are the only path from vault secrets to the system clipboard. - Secret copies do not enter Nuguland clipboard history and require no Niri clipboard changes. - Secret clipboard values expire after a short interval, but clearing never overwrites a subsequently changed clipboard. - Browser context uses local Linux accessibility and session interfaces; browser extensions and remote-debugging protocols are outside scope. - The observed browser address is neither persisted nor sent across the network. - Offline data remains encrypted at rest; no decrypted offline cache is introduced. - Favicon retrieval and caching disclose no vault contents to third-party favicon aggregators. - All visible labels are lowercase and both Nugu modes remain usable. ## Accepted design [Open the accepted split-view mockup](vault-widget.html). [Open the accepted in-widget unlock mockup](vault-unlock.html). The search/result pane remains visible beside the detail pane. Favorites are grouped first, URL-bearing items use cached favicons, and actions use icons rather than text labels. The detail pane adapts to every Vaultwarden item type. Locked state replaces vault content with the integrated master-password flow. ## Acceptance - First use, save, reload, edit, cancel, invalid settings, and failed persistence work without a tracked account profile. - Profile changes lock immediately, wait for native cleanup, and cannot reuse another identity's cache or late favicon results. - The configured profile connects to `vault.bugabinga.net` without embedding credentials in Nuguland configuration. - The same behavior contract passes against an official Bitwarden profile without UI changes. - Locked state reveals no item metadata and accepts the master password inside the widget. - Submit, cancel, invalid input, timeout, explicit lock, suspend, and shell exit leave no master password in UI state, arguments, environment, logs, or disk. - On-disk inspection finds no decrypted item values or plaintext authentication material. - Dependency and runtime inspection confirms no `rbw` library, Node runtime, `bw` or `rbw` CLI executable, `rbw-agent`, or standalone vault daemon dependency. - Desktop flows pass in a native Wayland session without Xwayland or an X11 server. - Search finds representative items of every supported type and selection updates the detail pane. - The Niri shortcut opens and focuses the widget from every workspace. - A focused browser promotes exact origin matches through the Linux-native route; unavailable browser context leaves retained state unchanged. - Context shortcuts copy each available target and report success without revealing its value. - Favorite toggling immediately moves matching items into or out of the favorites group and remains correct after vault sync. - Every supported item type exposes all available standard and custom fields without leaking concealed values. - Current and next TOTP values match independent generation before, during, and after a rollover; clicking each copies the shown value. - Query, selection, both scroll positions, expanded sections, and reveal state are unchanged after close and reopen. - Locking clears retained vault state and removes all item metadata and secrets from the surface. - Favicon cache hit, miss, failure, and fallback behavior work without third-party favicon aggregation. - Secret copy actions bypass Nuguland clipboard history, expire conditionally, and never overwrite newer clipboard content. - Cached vault items remain usable during network loss, while sync freshness and failures remain visible. - URL opening uses the desktop portal. - Pointer and keyboard flows, locked and failure states, both theme modes, and zero-warning lint pass.