{"id":51402112,"url":"https://github.com/adi21-dev/sysdeck","last_synced_at":"2026-07-04T08:00:32.440Z","repository":{"id":369093866,"uuid":"1288262608","full_name":"adi21-dev/sysdeck","owner":"adi21-dev","description":"A modern, lightweight remote control and IT administration dashboard powered by Rust and React.","archived":false,"fork":false,"pushed_at":"2026-07-03T14:45:12.000Z","size":409,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-03T16:18:04.542Z","etag":null,"topics":["cloudflare-tunnel","cross-platform","react","remote-access","rust","self-hosted","system-monitoring","tool","typescript"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/adi21-dev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-07-03T12:30:13.000Z","updated_at":"2026-07-03T14:45:15.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/adi21-dev/sysdeck","commit_stats":null,"previous_names":["adi21-dev/sysdeck"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/adi21-dev/sysdeck","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adi21-dev%2Fsysdeck","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adi21-dev%2Fsysdeck/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adi21-dev%2Fsysdeck/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adi21-dev%2Fsysdeck/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/adi21-dev","download_url":"https://codeload.github.com/adi21-dev/sysdeck/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adi21-dev%2Fsysdeck/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35114174,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-04T02:00:05.987Z","response_time":113,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cloudflare-tunnel","cross-platform","react","remote-access","rust","self-hosted","system-monitoring","tool","typescript"],"created_at":"2026-07-04T08:00:18.629Z","updated_at":"2026-07-04T08:00:32.433Z","avatar_url":"https://github.com/adi21-dev.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SysDeck — Remote System Agent\n\nA 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.\n\n## Architecture\n\n```\n┌─────────────────────────────────────────────────┐\n│  Host (Windows / Linux / macOS)                 │\n│                                                 │\n│  ┌─────────────────┐     ┌───────────────────┐  │\n│  │  Rust Backend   │◄───►│  SQLite (WAL)     │  │\n│  │  (Axum 0.7)     │     │  data.db          │  │\n│  ├─────────────────┤     └───────────────────┘  │\n│  │  /ws            │─── sysinfo telemetry       │\n│  │  /api/files     │─── file manager            │\n│  │  /api/scripts   │─── script engine           │\n│  │  /api/power     │─── power controls          │\n│  │  /api/windows   │─── window management       │\n│  │  /api/disks     │─── storage drives          │\n│  │  /api/processes │── top processes            │\n│  │  /api/sessions  │── user sessions            │\n│  │  /api/wol       │─── wake-on-LAN             │\n│  │  /api/settings  │─── settings admin          │\n│  │  /api/audit     │─── audit log               │\n│  │  /login         │─── password + TOTP auth    │\n│  │  /setup         │─── first-run wizard        │\n│  └──────┬──────────┘                            │\n│         │                                       │\n│  ┌──────▼───────┐     ┌────────────────────┐    │\n│  │  React SPA   │     │  cloudflared       │    │\n│  │  (Vite)      │     │  tunnel            │    │\n│  │  shadcn/ui   │     │  trycloudflare.com │    │\n│  │  Tailwind v4 │     └─────────┬──────────┘    │\n│  └──────────────┘               │               │\n└─────────────────────────────────┼───────────────┘\n                                  │\n                     ┌────────────▼───────────┐\n                     │  Public Internet       │\n                     │  (any browser, any OS) │\n                     └────────────────────────┘\n```\n\n## Tech Stack\n\n| Layer | Technology |\n|-------|-----------|\n| Backend | Rust, Axum 0.7, tokio, rusqlite (WAL), sysinfo |\n| Frontend | React 19, Vite, Tailwind CSS v4, shadcn/ui |\n| State | Zustand |\n| Charts | Recharts |\n| Icons | Lucide React |\n| Terminal | xterm.js |\n| Tunnel | Cloudflare Quick Tunnel (cloudflared) |\n| Auth | Argon2id, TOTP, keyring (OS Keychain), zxcvbn |\n| Rate Limit | governor |\n| System Tray | tray-icon (cross-platform) |\n| Secret Storage | keyring crate (Windows Credential Manager, macOS Keychain, Linux Secret Service) |\n\n## Platform Support\n\n| Feature | Windows 10/11 | Linux (x64/ARM64) | macOS 12+ |\n|---------|:-------------:|:-----------------:|:---------:|\n| Dashboard (CPU/RAM/disk/network) | ✅ | ✅ | ✅ |\n| WebSocket telemetry | ✅ | ✅ | ✅ |\n| File Manager (browse/upload/download) | ✅ | ✅ | ✅ |\n| Script Engine — PowerShell | ✅ | ❌ | ❌ |\n| Script Engine — Batch/cmd | ✅ | ❌ | ❌ |\n| Script Engine — Shell (bash) | ❌ | ✅ | ✅ |\n| Interactive Terminal (PTY) | ✅ | ✅ | ✅ |\n| Power Controls (shutdown/restart/sleep) | ✅ | ✅ (systemctl) | ✅ (osascript) |\n| Lock / Sign Out / Switch User | ✅ | ✅ (loginctl) | ✅ (CGSession) |\n| Window Management | ✅ (Win32) | ❌ | ❌ |\n| User Sessions (RDP) | ✅ (WTSAPI32) | ❌ | ❌ |\n| Audio Controls | ✅ | ❌ | ❌ |\n| Display Brightness | ✅ | ❌ | ❌ |\n| Network Status \u0026 Wi-Fi | ✅ | ✅ | ✅ |\n| Top Processes \u0026 Kill | ✅ | ✅ | ✅ |\n| Storage \u0026 Drives | ✅ | ✅ | ✅ |\n| Wake-on-LAN | ✅ | ✅ | ✅ |\n| System Tray | ✅ | ✅ (requires desktop) | ✅ |\n| Autostart | ✅ (Registry) | ✅ (.desktop) | ✅ (LaunchAgents) |\n| Cloudflare Tunnel | ✅ (amd64) | ✅ (amd64/arm64) | ✅ (amd64/arm64) |\n| Headless mode | ❌ | ✅ (no DISPLAY) | ❌ |\n| OS Keychain | ✅ (Credential Manager) | ✅ (Secret Service) | ✅ (Keychain) |\n\n\u003e **Note:** Features marked ❌ return a graceful \"not supported on this platform\" response — the server never panics or crashes.\n\n## Features\n\n- **Dashboard** — live CPU, RAM, network, disk, temperature via WebSocket (1s polling); real-time charts\n- **File Manager** — browse, upload (streaming, 500MB cap), download, delete, rename; table/grid views; path canonicalization with system directory block\n- **Script Engine** — run PowerShell/Batch (Windows) or bash (Linux/macOS) scripts; live streaming or wait-and-show output; 5-min timeout; 1MB output truncation; winget quick-commands\n- **Interactive Terminal** — PTY-backed terminal via WebSocket; xterm.js frontend; resize, multi-session; lazy-loaded chunk\n- **Window Management** — list, focus, minimize, restore, close windows via Win32 API *(Windows only)*\n- **Power Controls** — Shutdown, Restart, Sleep, Hibernate, Sign Out, Lock, Switch User; 5-second cancellation window; active-upload check before power off; two-step type-to-confirm\n- **Storage \u0026 Drives** — disk usage overview with progress bars (sysinfo)\n- **Top Processes** — CPU/memory usage, kill processes\n- **User Sessions** — list RDP/active sessions, disconnect or logoff via WTSAPI32 *(Windows only)*\n- **Wake-on-LAN** — send magic packet, save/manage MAC addresses\n- **Security** — password + TOTP login, short-lived JWT + opaque refresh tokens, OS Keychain-stored signing key, account lockout (5 failures → 15 min), IP rate limiting, CSP headers\n- **Admin Context** — settings routes restricted to localhost; remote tunnel users see a limited dashboard without admin access\n- **Audit Log** — append-only log of logins, file transfers, script executions, and security changes; filterable by event type and date range\n- **Setup Wizard** — server-rendered first-run flow: password strength check → TOTP QR → recovery codes → relay opt-in\n- **Dark Mode** — toggle in sidebar; follows system preference by default; persisted to localStorage\n- **System Tray** — cross-platform tray icon with autostart support (Windows: reg.exe, Linux: .desktop, macOS: LaunchAgents)\n- **Connection Status** — always-visible indicator (green/yellow/red) for WebSocket health\n- **Headless Linux** — automatic terminal-only mode when no display is available; prints SSH port-forwarding instructions\n- **Shutdown Sequence** — graceful WebSocket notification before the server stops\n\n## Getting Started\n\n### Prerequisites\n\n| OS | Requirements |\n|----|-------------|\n| Windows 10/11 | Rust toolchain (edition 2021), Node.js 20+ |\n| Linux | Rust toolchain, Node.js 20+, `dbus` (for Secret Service), `libappindicator3` (for tray) |\n| macOS 12+ | Xcode CLI tools (`xcode-select --install`), Rust toolchain, Node.js 20+ |\n\n### Quick Start\n\n```bash\ngit clone https://github.com/adi21-dev/sysdeck\ncd sysdeck\n\n# Backend (starts both backend + frontend automatically via build.rs)\ncd backend\ncargo run\n\n# Or for frontend development (hot-reload):\ncd frontend\nnpm install\nnpm run dev\n```\n\nOn first run, the backend:\n1. Creates `~/.local/share/SysDeck/` (Linux), `~/Library/Application Support/SysDeck/` (macOS), or `%LOCALAPPDATA%\\SysDeck\\` (Windows) for data and logs\n2. Stores the JWT signing key in your OS keychain (Credential Manager / Keychain / Secret Service)\n3. Downloads the correct `cloudflared` binary for your platform with SHA256 verification\n4. Binds to `localhost:3939` (falls back to random port)\n5. 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.\n6. 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).\n\n### Production Build\n\n```bash\ncd frontend \u0026\u0026 npm run build\ncd ../backend \u0026\u0026 cargo build --release\n```\n\nThe compiled binary is self-contained — the Vite build output is embedded via `rust-embed`. `build.rs` auto-triggers the frontend build during native compilation.\n\nThe release profile is optimized for size (`opt-level = \"z\"`, LTO, `panic = \"abort\"`, single codegen unit, symbols stripped) — expect a ~10 MB binary.\n\n### Cross-Compilation\n\nBuild for Linux from any host using [`cross`](https://github.com/cross-rs/cross):\n\n```bash\n# Pre-build frontend (not available inside Docker)\ncd frontend \u0026\u0026 npm run build \u0026\u0026 cd ..\n\n# Cross-compile the backend\ncd backend\ncross build --release --target x86_64-unknown-linux-gnu\n```\n\nThe resulting binary is at `backend/target/x86_64-unknown-linux-gnu/release/sysdeck-agent`.\n\n\u003e **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).\n\n### Building for All Platforms\n\n| Target | Host | Command |\n|--------|------|---------|\n| Windows x64 (native) | Windows | `cargo build --release` |\n| Linux x64 | Any (via `cross`) | `cross build --release --target x86_64-unknown-linux-gnu` |\n| Linux ARM64 | Any (via `cross`) | `cross build --release --target aarch64-unknown-linux-gnu` |\n| macOS x64 | macOS | `cargo build --release --target x86_64-apple-darwin` |\n| macOS ARM64 (Apple Silicon) | macOS | `cargo build --release --target aarch64-apple-darwin` |\n\n**Output binary locations:**\n\n| Target | Path | Extension |\n|--------|------|-----------|\n| Windows x64 | `backend/target/x86_64-pc-windows-msvc/release/` | `.exe` |\n| Linux x64 | `backend/target/x86_64-unknown-linux-gnu/release/` | *(none)* |\n| Linux ARM64 | `backend/target/aarch64-unknown-linux-gnu/release/` | *(none)* |\n| macOS x64 | `backend/target/x86_64-apple-darwin/release/` | *(none)* |\n| macOS ARM64 | `backend/target/aarch64-apple-darwin/release/` | *(none)* |\n\n\u003e Always pre-build the frontend (`cd frontend \u0026\u0026 npm run build`) before cross-compiling, since Node.js is not available in the cross Docker container.\n\n## Project Structure\n\n```\nsysdeck/\n├── backend/\n│   ├── build.rs              # Auto-builds frontend during native cargo build (skipped under cross)\n│   ├── src/\n│   │   ├── main.rs           # Entry point, keyring init, shutdown signal\n│   │   ├── lib.rs            # AppState, router, DB init, system tray, autostart\n│   │   ├── auth.rs           # JWT, keyring, TOTP, auth middleware, admin middleware\n│   │   ├── db.rs             # SQLite schema, telemetry/audit queries\n│   │   ├── telemetry.rs      # sysinfo polling engine (dedicated OS thread)\n│   │   ├── tunnel.rs         # Cloudflare tunnel manager (platform-aware download + lifecycle)\n│   │   ├── setup.rs          # Setup wizard state machine + handlers\n│   │   ├── settings.rs       # Password/TOTP/port/paths settings handlers\n│   │   ├── ws.rs             # WebSocket handler (telemetry + system events)\n│   │   ├── file_manager.rs   # File listing, upload, download, delete, rename\n│   │   ├── script.rs         # Script execution engine (PowerShell/bash/cmd)\n│   │   ├── power.rs          # Shutdown/restart/sleep/signout/lock + cancel (cross-platform)\n│   │   ├── audit.rs          # Audit log queries\n│   │   ├── terminal.rs       # PTY terminal (portable-pty, WebSocket bridge)\n│   │   ├── windows.rs        # Win32 window management (Windows only)\n│   │   ├── disks.rs          # Storage drive info (sysinfo::Disks)\n│   │   ├── process.rs        # Top processes + kill (sysinfo::System)\n│   │   ├── sessions.rs       # RDP/user sessions (Windows only — WTSAPI32)\n│   │   ├── hardware.rs       # Audio, display, dark mode controls\n│   │   ├── network.rs        # Network status, Wi-Fi, adapter controls\n│   │   ├── input.rs          # Mouse/keyboard input, clipboard, screenshot\n│   │   └── wol.rs            # Wake-on-LAN (UDP broadcast)\n│   ├── tests/\n│   │   ├── common/mod.rs     # Test helpers (test_app, login helpers)\n│   │   └── integration.rs    # Integration tests\n│   └── Cargo.toml\n├── cross/\n│   └── Dockerfile.x86_64-unknown-linux-gnu  # Custom Docker image for cross-compilation\n├── Cross.toml                                # cross configuration\n├── frontend/\n│   ├── e2e/\n│   │   ├── specs/            # Playwright spec files\n│   │   └── playwright.config.ts\n│   ├── src/\n│   │   ├── components/\n│   │   │   ├── layout/       # Sidebar, BottomNav, AppLayout, ProtectedRoute\n│   │   │   └── ui/           # shadcn/ui components\n│   │   ├── pages/            # Dashboard, Files, Scripts, Controls, Remote Desktop, Audit, Settings\n│   │   ├── hooks/            # WebSocket hook\n│   │   └── lib/              # Zustand stores, API utilities\n│   └── package.json\n├── LICENSE\n└── README.md\n```\n\n## API Endpoints\n\n### Authentication\n| Method | Path | Description |\n|--------|------|-------------|\n| GET | `/login` | Login page (frontend route) |\n| POST | `/login` | Authenticate (password + TOTP, form-urlencoded) |\n| GET | `/api/auth/check` | Validate JWT cookie, restore session |\n| POST | `/api/auth/refresh` | Refresh access token using refresh cookie |\n| POST | `/api/auth/logout` | Revoke current session |\n| GET | `/api/admin/check` | Check if request is from localhost |\n\n### Setup Wizard\n| Method | Path | Description |\n|--------|------|-------------|\n| GET | `/setup` | Server-rendered setup wizard |\n| POST | `/setup` | Submit setup step |\n| GET | `/api/setup/status` | Check if setup is complete |\n| POST | `/api/setup/password` | Set initial password (step 1) |\n| POST | `/api/setup/totp` | Generate TOTP secret (step 2) |\n| POST | `/api/setup/verify-totp` | Verify TOTP code (step 3) |\n| POST | `/api/setup/relay` | Set Cloudflare relay opt-in (step 4) |\n| POST | `/api/setup/finish` | Complete setup |\n\n### Dashboard \u0026 Telemetry\n| Method | Path | Description |\n|--------|------|-------------|\n| GET | `/ws` | Telemetry + system events WebSocket |\n| GET | `/api/telemetry/history` | Historical telemetry data (query params: `range`) |\n\n### File Management\n| Method | Path | Description |\n|--------|------|-------------|\n| GET | `/api/files/list` | List directory contents |\n| POST | `/api/files/upload` | Upload file (streaming, path in query) |\n| GET | `/api/files/download` | Download file |\n| POST | `/api/files/delete` | Delete file(s) |\n| POST | `/api/files/rename` | Rename file |\n| POST | `/api/files/mkdir` | Create directory |\n\n### Scripts\n| Method | Path | Description |\n|--------|------|-------------|\n| POST | `/api/scripts/execute` | Start script execution (supports `X-Api-Key` for webhooks) |\n| GET | `/ws/script/{id}` | Script output WebSocket |\n\n### Interactive Terminal\n| Method | Path | Description |\n|--------|------|-------------|\n| POST | `/api/terminal/create` | Create PTY session, returns `id` |\n| GET | `/ws/terminal/{id}` | Terminal I/O WebSocket (stdin/stdout/resize) |\n\n### Window Management *(Windows only)*\n| Method | Path | Description |\n|--------|------|-------------|\n| GET | `/api/windows` | List visible windows |\n| POST | `/api/windows/focus` | Bring window to foreground |\n| POST | `/api/windows/minimize` | Minimize window |\n| POST | `/api/windows/restore` | Restore window |\n| POST | `/api/windows/close` | Close window |\n\n### Power Controls\n| Method | Path | Description |\n|--------|------|-------------|\n| POST | `/api/power/execute` | Execute power action (shutdown/restart/sleep/hibernate/signout/lock/switchuser) |\n| POST | `/api/power/cancel` | Cancel pending power command |\n| GET | `/api/power/status` | Check pending power status |\n\n### Storage \u0026 Drives\n| Method | Path | Description |\n|--------|------|-------------|\n| GET | `/api/disks` | List mounted drives with usage stats |\n\n### Processes\n| Method | Path | Description |\n|--------|------|-------------|\n| GET | `/api/processes` | Top 15 processes by CPU usage |\n| POST | `/api/processes/kill` | Kill a process by PID |\n\n### User Sessions *(Windows only)*\n| Method | Path | Description |\n|--------|------|-------------|\n| GET | `/api/sessions` | List RDP/active sessions with usernames |\n| POST | `/api/sessions/action` | Disconnect or logoff a session |\n\n### Wake-on-LAN\n| Method | Path | Description |\n|--------|------|-------------|\n| POST | `/api/wol/wake` | Send magic packet to MAC address |\n| GET | `/api/wol/macs` | List saved MAC addresses |\n| POST | `/api/wol/macs` | Save a new MAC address |\n| POST | `/api/wol/macs/delete` | Remove a saved MAC address |\n\n### Settings *(localhost only)*\n| Method | Path | Description |\n|--------|------|-------------|\n| GET | `/api/settings/paths` | Get file access paths |\n| POST | `/api/settings/paths` | Set file access paths |\n| GET | `/api/settings/port` | Get current port |\n| POST | `/api/settings/port` | Set port (takes effect on restart) |\n| POST | `/api/settings/change-password` | Change password |\n| POST | `/api/settings/verify-totp` | Verify TOTP code |\n| POST | `/api/settings/reset-totp` | Reset TOTP secret |\n| GET | `/api/settings/export-db` | Download database backup |\n| GET | `/api/settings/download-logs` | Download log archive |\n| POST | `/api/settings/recovery-codes/regenerate` | Regenerate recovery codes |\n| GET | `/api/settings/sessions` | List active sessions |\n| POST | `/api/settings/sessions/revoke` | Revoke a session |\n| POST | `/api/settings/revoke-all` | Revoke all sessions |\n| GET | `/api/settings/webhook-key` | Get webhook API key |\n| POST | `/api/settings/webhook-key` | Rotate webhook API key |\n| GET | `/api/settings/relay` | Get relay (tunnel) opt-in status |\n| POST | `/api/settings/relay` | Set relay opt-in |\n\n### Audit Log\n| Method | Path | Description |\n|--------|------|-------------|\n| GET | `/api/audit/logs` | Query audit logs (query params: `event`, `from`, `to`, `offset`, `limit`) |\n\n## Testing\n\n```bash\n# Backend (57 tests: 17 unit + 40 integration)\ncd backend\ncargo test              # all tests\ncargo clippy            # zero warnings policy\n\n# Frontend\ncd frontend\nnpm run build           # tsc -b \u0026\u0026 vite build (type-check + bundle)\nnpm run lint            # oxlint --jsx-a11y-plugin\nnpm run test:e2e        # Playwright end-to-end tests\n```\n\n\u003e **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.\n\n## Security\n\n- **Passwords**: hashed with **Argon2id**; checked with **zxcvbn** (score ≥ 3/4 required)\n- **TOTP**: via **totp-rs** (SHA1, 30s window, 6 digits)\n- **Recovery codes**: 10 random Base32 strings, stored as Argon2id hashes\n- **JWT signing key**: 256-bit random, stored in **OS Keychain** via `keyring` crate (Windows Credential Manager, macOS Keychain, Linux Secret Service)\n- **Sessions**: short-lived access JWT (15 min) + opaque refresh token (7-day, SHA-256 hash in DB); multi-device coexistence\n- **Account lockout**: 5 failed attempts → 15-minute cooldown (in-memory, per user)\n- **IP rate limiting**: 60 req/min per IP (governor); skipped for `/setup` and `/login`\n- **CSP**: `default-src 'self'` with restricted style/img/script sources\n- **Admin route protection**: settings and admin endpoints blocked for non-localhost requests\n- **File path safety**: `std::fs::canonicalize` + platform-specific blocklist prevents directory traversal and system directory access\n- **Uploads**: streaming with 500MB hard cap, partial files cleaned up on error\n- **Scripts**: 5-minute timeout with forced kill; 1MB output truncation\n- **Webhook auth**: API key via `X-Api-Key` header for tokenless script execution\n\n## License\n\nMIT — see [LICENSE](LICENSE) for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadi21-dev%2Fsysdeck","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fadi21-dev%2Fsysdeck","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadi21-dev%2Fsysdeck/lists"}