Problem

Twingate's official Linux client is CLI-only. Every operation - connecting, disconnecting, switching accounts, picking an exit node, checking which resources are reachable - requires dropping to a terminal. That's fine for power users, but it's friction for anyone running Linux as their daily desktop, and it's a real adoption blocker for desktop-first users coming from the polished GUI clients on Windows and macOS.

Approach

Built a system tray application in Python + PyQt6 that wraps the official twingate CLI rather than reimplementing any of its functionality. Every operation invokes the CLI as a subprocess and parses its output to populate the UI. A background timer polls twingate status at a configurable interval (default 10 seconds) and updates a color-coded tray icon (green/connected, red/disconnected, yellow/connecting, gray/paused) plus a desktop notification on state changes.

Security was a first-order concern given the privilege boundary. Read-only operations run unprivileged; read-write operations (connect/disconnect/account switching) escalate through pkexec/polkit with a policy scoped exclusively to /usr/bin/twingate. User-provided arguments are validated through an allowlist regex before subprocess execution, and commands always run as argument lists - never through a shell - eliminating shell-injection vectors. The application never touches credentials; auth tokens stay entirely with the Twingate CLI.

Outcome

A drop-in tray app that turns the Linux CLI into a desktop-class client experience comparable to the Windows and macOS GUIs. Supports KDE, GNOME (with AppIndicator), Cinnamon, and XFCE. Distributed as a .deb package, install scripts, and source. Includes resource listing with one-click address copy, account switching and logout, exit node selection, single-instance enforcement, and an optional autostart .desktop entry. Bundled type checking (mypy), linting (ruff), and pytest test suite keep the codebase maintainable.

Tech Stack

Python 3.12+ PyQt6 polkit/pkexec PyInstaller Linux Desktop