You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A lightweight, cross-platform remote system management agent with a mobile-optimized web dashboard. Monitor CPU/RAM/disk/network, browse and transfer files, run scripts, control power, manage windows, open an interactive terminal, and wake machines on LAN — all through a secure Cloudflare tunnel. No RDP, no complex config.
git clone https://github.com/adi21-dev/sysdeck
cd sysdeck
# Backend (starts both backend + frontend automatically via build.rs)cd backend
cargo run
# Or for frontend development (hot-reload):cd frontend
npm install
npm run dev
On first run, the backend:
Creates ~/.local/share/SysDeck/ (Linux), ~/Library/Application Support/SysDeck/ (macOS), or %LOCALAPPDATA%\SysDeck\ (Windows) for data and logs
Stores the JWT signing key in your OS keychain (Credential Manager / Keychain / Secret Service)
Downloads the correct cloudflared binary for your platform with SHA256 verification
Binds to localhost:3939 (falls back to random port)
Generates a one-time Setup Key printed to the console window. This key acts as a security token to verify physical/owner access to the host machine.
Opens your browser to the first-run Setup Wizard, where you must enter this Setup Key to unlock configuration steps (admin credentials, TOTP, and remote access relay).
Production Build
cd frontend && npm run build
cd ../backend && cargo build --release
The compiled binary is self-contained — the Vite build output is embedded via rust-embed. build.rs auto-triggers the frontend build during native compilation.
The release profile is optimized for size (opt-level = "z", LTO, panic = "abort", single codegen unit, symbols stripped) — expect a ~10 MB binary.
# Pre-build frontend (not available inside Docker)cd frontend && npm run build &&cd ..
# Cross-compile the backendcd backend
cross build --release --target x86_64-unknown-linux-gnu
The resulting binary is at backend/target/x86_64-unknown-linux-gnu/release/sysdeck-agent.
How it works: Cross.toml maps the Linux target to a custom Docker image defined in cross/Dockerfile.x86_64-unknown-linux-gnu, which extends the official cross base image with libappindicator3-dev, libgtk-3-dev, libdbus-1-dev, and libsecret-1-dev. The build.rs detects cross-compilation via the CROSS environment variable and skips the frontend build (Node.js is not available in the container).
Start script execution (supports X-Api-Key for webhooks)
GET
/ws/script/{id}
Script output WebSocket
Interactive Terminal
Method
Path
Description
POST
/api/terminal/create
Create PTY session, returns id
GET
/ws/terminal/{id}
Terminal I/O WebSocket (stdin/stdout/resize)
Window Management (Windows only)
Method
Path
Description
GET
/api/windows
List visible windows
POST
/api/windows/focus
Bring window to foreground
POST
/api/windows/minimize
Minimize window
POST
/api/windows/restore
Restore window
POST
/api/windows/close
Close window
Power Controls
Method
Path
Description
POST
/api/power/execute
Execute power action (shutdown/restart/sleep/hibernate/signout/lock/switchuser)
POST
/api/power/cancel
Cancel pending power command
GET
/api/power/status
Check pending power status
Storage & Drives
Method
Path
Description
GET
/api/disks
List mounted drives with usage stats
Processes
Method
Path
Description
GET
/api/processes
Top 15 processes by CPU usage
POST
/api/processes/kill
Kill a process by PID
User Sessions (Windows only)
Method
Path
Description
GET
/api/sessions
List RDP/active sessions with usernames
POST
/api/sessions/action
Disconnect or logoff a session
Wake-on-LAN
Method
Path
Description
POST
/api/wol/wake
Send magic packet to MAC address
GET
/api/wol/macs
List saved MAC addresses
POST
/api/wol/macs
Save a new MAC address
POST
/api/wol/macs/delete
Remove a saved MAC address
Settings (localhost only)
Method
Path
Description
GET
/api/settings/paths
Get file access paths
POST
/api/settings/paths
Set file access paths
GET
/api/settings/port
Get current port
POST
/api/settings/port
Set port (takes effect on restart)
POST
/api/settings/change-password
Change password
POST
/api/settings/verify-totp
Verify TOTP code
POST
/api/settings/reset-totp
Reset TOTP secret
GET
/api/settings/export-db
Download database backup
GET
/api/settings/download-logs
Download log archive
POST
/api/settings/recovery-codes/regenerate
Regenerate recovery codes
GET
/api/settings/sessions
List active sessions
POST
/api/settings/sessions/revoke
Revoke a session
POST
/api/settings/revoke-all
Revoke all sessions
GET
/api/settings/webhook-key
Get webhook API key
POST
/api/settings/webhook-key
Rotate webhook API key
GET
/api/settings/relay
Get relay (tunnel) opt-in status
POST
/api/settings/relay
Set relay opt-in
Audit Log
Method
Path
Description
GET
/api/audit/logs
Query audit logs (query params: event, from, to, offset, limit)
Testing
# Backend (57 tests: 17 unit + 40 integration)cd backend
cargo test# all tests
cargo clippy # zero warnings policy# Frontendcd frontend
npm run build # tsc -b && vite build (type-check + bundle)
npm run lint # oxlint --jsx-a11y-plugin
npm run test:e2e # Playwright end-to-end tests
Note: One test (test_set_audio_device) is expected to fail on machines without a switchable audio device — this is a known pre-existing hardware limitation.
Security
Passwords: hashed with Argon2id; checked with zxcvbn (score ≥ 3/4 required)
TOTP: via totp-rs (SHA1, 30s window, 6 digits)
Recovery codes: 10 random Base32 strings, stored as Argon2id hashes
JWT signing key: 256-bit random, stored in OS Keychain via keyring crate (Windows Credential Manager, macOS Keychain, Linux Secret Service)