The challenge
Developers juggle sensitive credentials — database URIs, API tokens, SSH keys — across scattered terminals and config files, risking accidental exposure and repetitive environment setup.
The approach
Built a Tauri v2 (Rust) desktop app with a Next.js 16 / TypeScript UI.
What shipped- An AES-256-GCM encrypted secret vault
- A native PTY-backed terminal for recipe-based workflows with saved presets
- A multi-database explorer (SQLite, MongoDB, PostgreSQL, MySQL, Redis)
- A project runner that classifies monorepos and workspaces
- A WebRTC relay for shared terminal sessions
- An MCP server that exposes the app's own tools to external clients
- Live CPU/RAM/disk telemetry
The outcome
A single secure control panel for local dev environments, shipped as signed cross-platform installers with an object-storage-hosted update manifest driving in-app auto-updates, alongside a marketing, docs and licensing site.
How CmdVault is put together
A Tauri 2 desktop app: a React UI drives a Rust core through typed IPC commands. The core owns the encrypted vault, native terminals, storage and an AI tool-use loop; a companion Next.js service on cmd.rohith-a.me handles accounts, AI credits, encrypted shares, live-session discovery and release updates.
- database engines in the explorer
- 5
- PBKDF2 rounds on shared files
- 250k
- TTL on live-session data
- 2 h
- permission tiers for a shared session
- 3
01 · Desktop UI
client
Dashboard UI
Next.js · React · Zustand
webview
third-party
MCP clients
external AI tools
02 · IPC boundary
gateway
IPC command layer
Tauri commands
one module per surface
03 · Rust core
service
Secure vault
Argon2 · AES-256-GCM
service
PTY manager
interactive terminals
worker
Command executor
recipes, workflows, AI commands
service
AI assistant
tool-use loop, confirm to run
service
MCP server
same tools as the assistant
04 · Local data
database
SQLite
profiles, recipes, settings
database
User's MongoDB
optional sync backend
05 · CmdVault cloud
service
cmd.rohith-a.me API
Next.js
auth, credits, shares, updates
database
Live cluster
MongoDB
signalling, chat · 2 h TTL
object store
Release bucket
OCI Object Storage
latest.json, signed installers
client
Peer device
shared terminal
06 · Third-party
third-party
Anthropic API
user's own key
third-party
Google · GitHub OAuth
third-party
Image-gen provider
behind the credits API
17 connections
- Dashboard UI→IPC command layerinvoke
- IPC command layer→Dashboard UIevents · token stream · async
- MCP clients→MCP serverMCP
- IPC command layer→Secure vaultunlock · decrypt
- IPC command layer→PTY managerspawn · stream
- IPC command layer→AI assistant
- IPC command layer→Command executorrun recipe
- AI assistant→Command executorrun after approval
- AI assistant→Anthropic APIMessages API
- IPC command layer→SQLitestorage router
- IPC command layer→User's MongoDBstorage router · optional
- IPC command layer→cmd.rohith-a.me APIsession · update · live URI
- cmd.rohith-a.me API→Google · GitHub OAuthsign-in
- cmd.rohith-a.me API→Release bucketresolve latest
- cmd.rohith-a.me API→Image-gen providerproxied jobs
- IPC command layer→Live clusteroffer · answer · ICE
- Dashboard UI→Peer deviceWebRTC data channel · optional
Request flow · Sharing a live terminal session
- 1The core fetches the live-cluster URI from the CmdVault API and caches it, so a burst of ICE candidates costs one request, not one each.
- 2The host posts its WebRTC offer and ICE candidates to the live_sessions collection; the peer finds them by session code and answers.
- 3Once connected, terminal output streams from the host UI to the peer over a terminal-io data channel; the cluster only ever carried signalling, which expires after two hours.
- 4Input from the peer is gated by tier (view only, assisted, full control) before it can reach the host terminal.
Design decisions
- Keys derived, never stored
- The master password goes through Argon2 with a per-install salt to derive the AES-256-GCM key, held only in memory while unlocked; repeated failed unlocks trigger a lockout.
- AI keys never reach the webview
- The Anthropic key is a vault-encrypted setting read only in Rust; the tool-use loop runs there and every command it wants to run waits for the user to confirm.
- Zero-knowledge sharing
- Shared files are encrypted in the client with Web Crypto (PBKDF2, 250k iterations); the server stores opaque ciphertext and never sees a password.
- Two clusters, never merged
- The user's own MongoDB holds their data; the service cluster holds signalling. Separate client pools mean a user's settings can never redirect live traffic.
- Contracts checked in CI
- A CI step verifies every IPC command the UI calls exists in the Rust core; releases ship through a signed manifest in object storage.
Trade-offs & known limits
- Signalling is polled through MongoDB rather than pushed over a socket: simple to operate, but adds latency to connection setup.
- Paid credits are wired behind a provider interface with no payment processor attached yet; checkout reports "coming soon".
Have something similar in mind?
I'm open for freelance and contract work — let's talk about what you're building.